1 Open issues

See ISSUES.md.

2 Background

The program creates staging datasets from the pre-staging datasets of the Colorado Medicaid data.

The pre-staging datasets simply convert the raw data files to SAS readable files. No row exclusions or column exclusions are made. No column creation is done, either. See makePreStagedDataFiles.* for details. Even better, see the commit with the tag Colorado in the DataRepository git repo.

However, the staging datasets are smaller versions of the data. Row exclusions are made. New columns are created. The datasets, however, are not aggregated.

The exceptions are mem_detail* and cdps*. These datasets are aggregated at the person-quarter level.

Datasets are written to \\chse.ohsu.edu\Share\DataRepository\Colorado Medicaid\Staged. See pathStaged object assignment.

Below is the processing sequence of the R Markdown files.

## 1: preliminaries.Rmd
## 2: makeHelpers.Rmd
## 3: makeClientSnapshot.Rmd
## 4: makeClaims.Rmd
## 5: makeRxClaims.Rmd
## 6: makeICD9.Rmd
## 7: makeIndicators.Rmd
## 8: makeCohortVariable.Rmd
## 9: runCDPS.Rmd
## 10: mergePrices.Rmd
## 11: dumpFileInfo.Rmd
## 12: copyDatasets.Rmd
## Warning: package 'DiagrammeR' was built under R version 3.1.3

3 Preliminaries

Point the pathScripts object to your local repository. The callSAS function will need to know where to look for the .sas scripts and where to put the .log files.

Define a temp path for storing RData files.

Define a Staged data path for storing permanent RData files.

pathScripts <- getwd()
pathTemp <- "E:\\Share\\Temp\\chanb\\Colorado Medicaid"
pathData <- "E:\\Share\\DataRepository\\Colorado Medicaid"
pathStaged <- sprintf("%s\\%s", pathData, "Staged")

Check for and load packages. Source the loadPkg function. Source is found at this gist.

## Loading required package: chse
## Loading required package: data.table
## Warning: package 'data.table' was built under R version 3.1.3
## Loading required package: foreign
## Loading required package: readstata13
## Loading required package: sas7bdat
## Loading required package: xlsx
## Warning: package 'xlsx' was built under R version 3.1.3
## Loading required package: rJava
## Warning: package 'rJava' was built under R version 3.1.3
## Loading required package: xlsxjars
## Warning: package 'xlsxjars' was built under R version 3.1.3

Set missing value strings.

na.strings <- c("NA", "", ".", "NO DATA")

Source the callSAS function. Source is found at this gist.

setInternet2()
source("https://gist.githubusercontent.com/benjamin-chan/73019d049763cff1d448/raw/94ed5862dc961ea1822e2f1a01752feb1ce01f39/callSAS.r")

Copy the SAS format library from the PreStaged folder to the Staged folder.

file.copy(sprintf("%s\\%s\\formats.sas7bcat", pathData, "PreStaged"),
          sprintf("%s\\%s\\formats.sas7bcat", pathData, "Staged"),
          overwrite=TRUE)
## [1] TRUE

Define function to create metadata object.

makeMetadata <- function(source) {
  list(timeStamp = Sys.time(),
       sourceScript = source)
}

4 Make helper lookup datasets

Run this script before any HCPF data is read in.

This borrows heavily from Stephanie’s MedicaidDataProcessing\Staging_Code\APAC\010CreateHelperFunctions.Rmd. Which borrows heavily from Ben’s 012CreateHelperFunctions.Rmd.

4.1 HCPF Valid Values codebook

Read HCPF’s supplied codebook.

pathSource <- "E:\\Share\\DataRepository\\Colorado Medicaid\\Medicaid_UCDSPH"
f <- "VALID_VALUES.TXT"
validValues <- fread(sprintf("%s\\\\%s", pathSource, f), sep="|", stringsAsFactors=FALSE)
## 
Read 64.9% of 862968 rows
Read 862968 rows and 4 (of 4) columns from 0.044 GB file in 00:00:03
str(validValues)
## Classes 'data.table' and 'data.frame':   862968 obs. of  4 variables:
##  $ VALID_VALUE_DSC   : chr  "AIR AMBULANCE REQUIRED" "AMB TRANSPORT TO ALT FAC REQD" "NONER STRETCHER TRANSP REQD" "PREADM SCREENING EXEMPT" ...
##  $ VALID_VALUE_SRC_CD: chr  "CO" "CO" "CO" "CO" ...
##  $ REFRESH_DT        : chr  "9/28/2014 12:00:00 AM" "9/28/2014 12:00:00 AM" "9/28/2014 12:00:00 AM" "9/28/2014 12:00:00 AM" ...
##  $ VALID_VALUE_CD    : chr  "AK" "AL" "AM" "AN" ...
##  - attr(*, ".internal.selfref")=<externalptr>
rm(pathSource, f)

Create named vectors for vector indexing. See Nesterko.com, part (b).

makeNamedVec <- function (src_cd) {
  namedVec <- validValues[VALID_VALUE_SRC_CD == src_cd, VALID_VALUE_CD]
  names(namedVec) <- validValues[VALID_VALUE_SRC_CD == src_cd, VALID_VALUE_DSC]
  show(namedVec)
  namedVec
}
lBatchDocType <- makeNamedVec("BD")
##          ADJUSTMENT CLAIMS ELECTRONIC FEE FOR SERVICE 
##                        "A"                        "B" 
##         CLEAN PAPER CLAIMS         DIRTY PAPER CLAIMS 
##                        "C"                        "D" 
##           ENCOUNTER CLAIMS    DENIED ENCOUNTER CLAIMS 
##                        "E"                        "F" 
##     RECONSIDERATION CLAIMS                    NO DATA 
##                        "R"                         ""
lClaimType <- makeNamedVec("CM")
##              PHARMACY CLAIM                   INPATIENT 
##                         "A"                         "B" 
##                  OUTPATIENT            NURSING FACILITY 
##                         "C"                         "D" 
##      PRACTITIONER/PHYSICIAN                      DENTAL 
##                         "E"                         "F" 
##      INDEPENDENT LABORATORY              MEDICAL SUPPLY 
##                         "H"                         "I" 
##                 HOME HEALTH                       EPSDT 
##                         "J"                         "K" 
##              TRANSPORTATION      MCARE PART A CROSSOVER 
##                         "L"                         "M" 
##      MCARE PART B CROSSOVER MCARE UB04 PART B CROSSOVER 
##                         "N"                         "O" 
##                 HCBS WAIVER       FINANCIAL TRANSACTION 
##                         "W"                         "X" 
##         REPLACEMENT REQUEST              CREDIT REQUEST 
##                         "Y"                         "Z" 
##        CICP INPATIENT CLAIM       CICP OUTPATIENT CLAIM 
##                         "1"                         "2" 
##                  CAPITATION                     NO DATA 
##                         "3"                          ""

4.2 Urban/rural designation

NEED TO ACQUIRE

4.3 BETOS

Create named vectors for vector indexing.

Create a named vector for Berenson-Eggers Type of Service (BETOS) codes. Use the 2013 BETOS file. File specifications are in the r-me-bet13.txt file.

version <- "13"
setInternet2()
url <- sprintf("http://www.cms.gov/MedHCPCSGenInfo/downloads/betpuf%s.zip", version)
f <- tempfile()
download.file(url, f)
## Warning in download.file(url, f): downloaded length 45085 != reported
## length 45085
t <- unz(f, sprintf("betpuf%s.txt", version))
dfBetos <- read.fwf(t, c(5, 1, 3, 8), header=FALSE, stringsAsFactors=FALSE, fill=TRUE, strip.white=TRUE)
names(dfBetos) <- c("codeHcpcs", "filler", "codeBetos", "dateTermination")
codeBetos <- dfBetos$codeBetos
names(codeBetos) <- dfBetos$codeHcpcs
str(dfBetos)
## 'data.frame':    16406 obs. of  4 variables:
##  $ codeHcpcs      : chr  "0001F" "0005F" "00100" "00102" ...
##  $ filler         : logi  NA NA NA NA NA NA ...
##  $ codeBetos      : chr  "Z2" "Z2" "P0" "P0" ...
##  $ dateTermination: int  NA NA NA NA NA NA NA NA NA NA ...
rm(version, url, f, t)

Create factor levels and labels for BETOS categories. These will be used to group BETOS codes into a factor variable. Ignore the warning; it doesn’t seem to break things.

levels <- c("M", "P", "I", "T", "D", "O", "Y", "Z")
labels <- c("E & M", "Procedures", "Imaging", "Tests", "DME", "Other", rep("Except./unclass.", 2))
dfBetos$facBetos <- factor(substr(dfBetos$codeBetos, 1, 1), levels=levels, labels=labels)
## Warning in `levels<-`(`*tmp*`, value = if (nl == nL) as.character(labels)
## else paste0(labels, : duplicated levels in factors are deprecated
dfBetos$facBetos <- droplevels(dfBetos$facBetos)
## Warning in `levels<-`(`*tmp*`, value = if (nl == nL) as.character(labels)
## else paste0(labels, : duplicated levels in factors are deprecated
table(dfBetos$facBetos)
## 
##            E & M       Procedures          Imaging            Tests 
##             1246             6750              952             1883 
##              DME            Other Except./unclass. 
##             2440             1070             2065
facBetos <- dfBetos$facBetos
names(facBetos) <- dfBetos$codeHcpcs
rm(levels, labels)

4.4 Visit Indicators

Create HEDIS helper lists for visit indicators.

Use HEDIS 2014 value sets to flag a claim as:

  • Acute inpatient
  • Nonacute inpatient
  • Inpatient (see page 292, Inpatient Utilization–General Hospital/Acute Care (IPU), of the HEDIS 2014 documentation)
    • IPU Exclusions MS-DRG
    • Maternity MS-DRG Value Set
    • Surgery MS-DRG Value Set
    • Medicine MS-DRG Value Set
    • Newborns/Neonates MS-DRG Value Set
    • Maternity Diagnosis Value Set
    • Maternity Value Set
    • Surgery Value Set
  • Observation
  • ED Value Set
  • ED Procedure Code Value Set
  • ED POS Value Set
  • Outpatient (see page 289, Inpatient UtilizationâGeneral Hospital/Acute Care (IPU), of the HEDIS 2014 documentation)
    • Ambulatory Outpatient Visits Value Set
  • Outpatient, expanded
    • Outpatient OR Ambulatory Outpatient Visits OR Ambulatory Visits OR Outpatient CPT
  • Pregnancy
    • To be used to code the cohort variable downstream
    • We realized that the Maternity and the Delivery value sets didn’t really capture what we wanted out of this comorbidity
      • Maternity captures the inpatient experience
      • Delivery captures what happens in the process of delivering a birth
    • The Pregnancy value set captures events leading to and including the delivery
    • It also captures events during a pregnancy that does not result in a live birth

Side note: the Pregnancy Diagnosis value set contains a subset of the codes in the Pregnancy value set.

Read HEDIS value set data.

f <- file.path("E:", "Share", "LookupTablesAndCrosswalks", "HEDIS 2014 Volume 2 10.01.13", "HEDIS_2014_Lookup_Codes.txt")
dfHedisValueSets <- read.delim(f, header=TRUE, stringsAsFactors=FALSE)
v <- c("Value.Set.Name", "Code.System", "Code", "Definition")
dfHedisValueSets <- dfHedisValueSets[, v]
rm(f, v)

Pad leading zeros to the HEDIS table revenue codes.

isRev <- dfHedisValueSets$Code.System == "UBREV"
is3Digits <- grepl("^[0-9]{3}$", dfHedisValueSets$Code)
isToFix <- isRev & is3Digits
message("Before")
## Before
head(dfHedisValueSets[isToFix, ])
##     Value.Set.Name Code.System Code
## 49 Acute Inpatient       UBREV  100
## 50 Acute Inpatient       UBREV  101
## 51 Acute Inpatient       UBREV  110
## 52 Acute Inpatient       UBREV  111
## 53 Acute Inpatient       UBREV  112
## 54 Acute Inpatient       UBREV  113
##                                     Definition
## 49 All-inclusive room and board plus ancillary
## 50                All-inclusive room and board
## 51                                     General
## 52                        Medical/surgical/GYN
## 53                             Obstetrics (OB)
## 54                                   Pediatric
dfHedisValueSets$Code[isToFix] <- paste0("0", dfHedisValueSets$Code[isToFix])
message("After")
## After
head(dfHedisValueSets[isToFix, ])
##     Value.Set.Name Code.System Code
## 49 Acute Inpatient       UBREV 0100
## 50 Acute Inpatient       UBREV 0101
## 51 Acute Inpatient       UBREV 0110
## 52 Acute Inpatient       UBREV 0111
## 53 Acute Inpatient       UBREV 0112
## 54 Acute Inpatient       UBREV 0113
##                                     Definition
## 49 All-inclusive room and board plus ancillary
## 50                All-inclusive room and board
## 51                                     General
## 52                        Medical/surgical/GYN
## 53                             Obstetrics (OB)
## 54                                   Pediatric
rm(isRev, is3Digits, isToFix)

Verify that HCPF does not pad 2-digit DRG codes with leading zeros. Therefore, no need to append a leading zero to the HEDIS table DRG code.

Create a factor variable for the code system. Ignore the warning; it doesn’t seem to break things.

labels <- c(rep("cpt", 2), "icd9cm", "icd9pcs", "loinc", "drg", "pos", "ubRev", "typeOfBill")
dfHedisValueSets$codeSysVar <- factor(dfHedisValueSets$Code.System, labels=labels)
## Warning in `levels<-`(`*tmp*`, value = if (nl == nL) as.character(labels)
## else paste0(labels, : duplicated levels in factors are deprecated
dfHedisValueSets$codeSysVar <- droplevels(dfHedisValueSets$codeSysVar)
## Warning in `levels<-`(`*tmp*`, value = if (nl == nL) as.character(labels)
## else paste0(labels, : duplicated levels in factors are deprecated
table(dfHedisValueSets$Code.System, dfHedisValueSets$codeSysVar)
##          
##             cpt icd9cm icd9pcs loinc   drg   pos ubRev typeOfBill
##   CPT      8556      0       0     0     0     0     0          0
##   HCPCS     959      0       0     0     0     0     0          0
##   ICD9CM      0  11544       0     0     0     0     0          0
##   ICD9PCS     0      0     430     0     0     0     0          0
##   LOINC       0      0       0   784     0     0     0          0
##   MSDRG       0      0       0     0   749     0     0          0
##   POS         0      0       0     0     0   154     0          0
##   UBREV       0      0       0     0     0     0   644          0
##   UBTOB       0      0       0     0     0     0     0        170
rm(labels)

Define a helper function.

makeList <- function (valueSetName) {
  v <- c("Value.Set.Name", "Code.System", "Code", "Definition")
  df <- dfHedisValueSets[dfHedisValueSets[, "Value.Set.Name"] == valueSetName, c(v, "codeSysVar")]
  t <- table(droplevels(df$codeSysVar), df$Value.Set.Name)
  l <- list(valueSetName = valueSetName,
            summary = t,
            cpt = as.character(df[df$codeSysVar == "cpt", "Code"]),
            icd9cm = gsub("\\.", "", df[df$codeSysVar == "icd9cm", "Code"]),
            icd9pcs = gsub("\\.", "", df[df$codeSysVar == "icd9pcs", "Code"]),
            drg = as.character(df[df$codeSysVar == "drg", "Code"]),
            ubRev = unique(df[df$codeSysVar == "ubRev", "Code"]),
            pos = df[df$codeSysVar == "pos", "Code"],
            typeOfBill = as.character(df[df$codeSysVar == "typeOfBill", "Code"]))
  show(l)
  l
}

Create lists for HEDIS value set indicators lookups. All of these only use procedure codes and revenue codes, so use the helper function makeList.

lCodesAcuteInpatient <- makeList("Acute Inpatient")
## $valueSetName
## [1] "Acute Inpatient"
## 
## $summary
##        
##         Acute Inpatient
##   cpt                14
##   ubRev              58
## 
## $cpt
##  [1] "99221" "99222" "99223" "99231" "99232" "99233" "99238" "99239"
##  [9] "99251" "99252" "99253" "99254" "99255" "99291"
## 
## $icd9cm
## character(0)
## 
## $icd9pcs
## character(0)
## 
## $drg
## character(0)
## 
## $ubRev
##  [1] "0100" "0101" "0110" "0111" "0112" "0113" "0114" "0119" "0120" "0121"
## [11] "0122" "0123" "0124" "0129" "0130" "0131" "0132" "0133" "0134" "0139"
## [21] "0140" "0141" "0142" "0143" "0144" "0149" "0150" "0151" "0152" "0153"
## [31] "0154" "0159" "0160" "0164" "0167" "0169" "0200" "0201" "0202" "0203"
## [41] "0204" "0206" "0207" "0208" "0209" "0210" "0211" "0212" "0213" "0214"
## [51] "0219" "0720" "0721" "0722" "0723" "0724" "0729" "0987"
## 
## $pos
## character(0)
## 
## $typeOfBill
## character(0)
lCodesNonacuteInpatient <- makeList("Nonacute Inpatient")
## $valueSetName
## [1] "Nonacute Inpatient"
## 
## $summary
##        
##         Nonacute Inpatient
##   cpt                   19
##   ubRev                 22
## 
## $cpt
##  [1] "99304" "99305" "99306" "99307" "99308" "99309" "99310" "99315"
##  [9] "99316" "99318" "99324" "99325" "99326" "99327" "99328" "99334"
## [17] "99335" "99336" "99337"
## 
## $icd9cm
## character(0)
## 
## $icd9pcs
## character(0)
## 
## $drg
## character(0)
## 
## $ubRev
##  [1] "0118" "0128" "0138" "0148" "0158" "0190" "0191" "0192" "0193" "0194"
## [11] "0199" "0524" "0525" "0550" "0551" "0552" "0559" "0660" "0661" "0662"
## [21] "0663" "0669"
## 
## $pos
## character(0)
## 
## $typeOfBill
## character(0)
lCodesIPUExclusionsDRG <- makeList("IPU Exclusions MS-DRG")
## $valueSetName
## [1] "IPU Exclusions MS-DRG"
## 
## $summary
##      
##       IPU Exclusions MS-DRG
##   drg                    15
## 
## $cpt
## character(0)
## 
## $icd9cm
## character(0)
## 
## $icd9pcs
## character(0)
## 
## $drg
##  [1] "876" "880" "881" "882" "883" "884" "885" "886" "887" "894" "895"
## [12] "896" "897" "945" "946"
## 
## $ubRev
## character(0)
## 
## $pos
## character(0)
## 
## $typeOfBill
## character(0)
lCodesMaternityDRG <- makeList("Maternity MS-DRG")
## $valueSetName
## [1] "Maternity MS-DRG"
## 
## $summary
##      
##       Maternity MS-DRG
##   drg               15
## 
## $cpt
## character(0)
## 
## $icd9cm
## character(0)
## 
## $icd9pcs
## character(0)
## 
## $drg
##  [1] "765" "766" "767" "768" "769" "770" "774" "775" "776" "777" "778"
## [12] "779" "780" "781" "782"
## 
## $ubRev
## character(0)
## 
## $pos
## character(0)
## 
## $typeOfBill
## character(0)
lCodesSurgeryDRG <- makeList("Surgery MS-DRG")
## $valueSetName
## [1] "Surgery MS-DRG"
## 
## $summary
##      
##       Surgery MS-DRG
##   drg            370
## 
## $cpt
## character(0)
## 
## $icd9cm
## character(0)
## 
## $icd9pcs
## character(0)
## 
## $drg
##   [1] "001" "002" "003" "004" "005" "006" "007" "008" "10"  "11"  "12" 
##  [12] "13"  "14"  "16"  "17"  "20"  "21"  "22"  "23"  "24"  "25"  "26" 
##  [23] "27"  "28"  "29"  "30"  "31"  "32"  "33"  "34"  "35"  "36"  "37" 
##  [34] "38"  "39"  "40"  "41"  "42"  "113" "114" "115" "116" "117" "129"
##  [45] "130" "131" "132" "133" "134" "135" "136" "137" "138" "139" "163"
##  [56] "164" "165" "166" "167" "168" "215" "216" "217" "218" "219" "220"
##  [67] "221" "222" "223" "224" "225" "226" "227" "228" "229" "230" "231"
##  [78] "232" "233" "234" "235" "236" "237" "238" "239" "240" "241" "242"
##  [89] "243" "244" "245" "246" "247" "248" "249" "250" "251" "252" "253"
## [100] "254" "255" "256" "257" "258" "259" "260" "261" "262" "263" "264"
## [111] "265" "326" "327" "328" "329" "330" "331" "332" "333" "334" "335"
## [122] "336" "337" "338" "339" "340" "341" "342" "343" "344" "345" "346"
## [133] "347" "348" "349" "350" "351" "352" "353" "354" "355" "356" "357"
## [144] "358" "405" "406" "407" "408" "409" "410" "411" "412" "413" "414"
## [155] "415" "416" "417" "418" "419" "420" "421" "422" "423" "424" "425"
## [166] "453" "454" "455" "456" "457" "458" "459" "460" "461" "462" "463"
## [177] "464" "465" "466" "467" "468" "469" "470" "471" "472" "473" "474"
## [188] "475" "476" "477" "478" "479" "480" "481" "482" "483" "484" "485"
## [199] "486" "487" "488" "489" "490" "491" "492" "493" "494" "495" "496"
## [210] "497" "498" "499" "500" "501" "502" "503" "504" "505" "506" "507"
## [221] "508" "509" "510" "511" "512" "513" "514" "515" "516" "517" "570"
## [232] "571" "572" "573" "574" "575" "576" "577" "578" "579" "580" "581"
## [243] "582" "583" "584" "585" "614" "615" "616" "617" "618" "619" "620"
## [254] "621" "622" "623" "624" "625" "626" "627" "628" "629" "630" "652"
## [265] "653" "654" "655" "656" "657" "658" "659" "660" "661" "662" "663"
## [276] "664" "665" "666" "667" "668" "669" "670" "671" "672" "673" "674"
## [287] "675" "707" "708" "709" "710" "711" "712" "713" "714" "715" "716"
## [298] "717" "718" "734" "735" "736" "737" "738" "739" "740" "741" "742"
## [309] "743" "744" "745" "746" "747" "748" "749" "750" "799" "800" "801"
## [320] "802" "803" "804" "820" "821" "822" "823" "824" "825" "826" "827"
## [331] "828" "829" "830" "853" "854" "855" "856" "857" "858" "901" "902"
## [342] "903" "904" "905" "906" "907" "908" "909" "927" "928" "929" "939"
## [353] "940" "941" "955" "956" "957" "958" "959" "969" "970" "981" "982"
## [364] "983" "984" "985" "986" "987" "988" "989"
## 
## $ubRev
## character(0)
## 
## $pos
## character(0)
## 
## $typeOfBill
## character(0)
lCodesMedicineDRG <- makeList("Medicine MS-DRG")
## $valueSetName
## [1] "Medicine MS-DRG"
## 
## $summary
##      
##       Medicine MS-DRG
##   drg             342
## 
## $cpt
## character(0)
## 
## $icd9cm
## character(0)
## 
## $icd9pcs
## character(0)
## 
## $drg
##   [1] "52"  "53"  "54"  "55"  "56"  "57"  "58"  "59"  "60"  "61"  "62" 
##  [12] "63"  "64"  "65"  "66"  "67"  "68"  "69"  "70"  "71"  "72"  "73" 
##  [23] "74"  "75"  "76"  "77"  "78"  "79"  "80"  "81"  "82"  "83"  "84" 
##  [34] "85"  "86"  "87"  "88"  "89"  "90"  "91"  "92"  "93"  "94"  "95" 
##  [45] "96"  "97"  "98"  "99"  "100" "101" "102" "103" "121" "122" "123"
##  [56] "124" "125" "146" "147" "148" "149" "150" "151" "152" "153" "154"
##  [67] "155" "156" "157" "158" "159" "175" "176" "177" "178" "179" "180"
##  [78] "181" "182" "183" "184" "185" "186" "187" "188" "189" "190" "191"
##  [89] "192" "193" "194" "195" "196" "197" "198" "199" "200" "201" "202"
## [100] "203" "204" "205" "206" "207" "208" "280" "281" "282" "283" "284"
## [111] "285" "286" "287" "288" "289" "290" "291" "292" "293" "294" "295"
## [122] "296" "297" "298" "299" "300" "301" "302" "303" "304" "305" "306"
## [133] "307" "308" "309" "310" "311" "312" "313" "314" "315" "316" "368"
## [144] "369" "370" "371" "372" "373" "374" "375" "376" "377" "378" "379"
## [155] "380" "381" "382" "383" "384" "385" "386" "387" "388" "389" "390"
## [166] "391" "392" "393" "394" "395" "432" "433" "434" "435" "436" "437"
## [177] "438" "439" "440" "441" "442" "443" "444" "445" "446" "533" "534"
## [188] "535" "536" "537" "538" "539" "540" "541" "542" "543" "544" "545"
## [199] "546" "547" "548" "549" "550" "551" "552" "553" "554" "555" "556"
## [210] "557" "558" "559" "560" "561" "562" "563" "564" "565" "566" "592"
## [221] "593" "594" "595" "596" "597" "598" "599" "600" "601" "602" "603"
## [232] "604" "605" "606" "607" "637" "638" "639" "640" "641" "642" "643"
## [243] "644" "645" "682" "683" "684" "685" "686" "687" "688" "689" "690"
## [254] "691" "692" "693" "694" "695" "696" "697" "698" "699" "700" "722"
## [265] "723" "724" "725" "726" "727" "728" "729" "730" "754" "755" "756"
## [276] "757" "758" "759" "760" "761" "808" "809" "810" "811" "812" "813"
## [287] "814" "815" "816" "834" "835" "836" "837" "838" "839" "840" "841"
## [298] "842" "843" "844" "845" "846" "847" "848" "849" "862" "863" "864"
## [309] "865" "866" "867" "868" "869" "870" "871" "872" "913" "914" "915"
## [320] "916" "917" "918" "919" "920" "921" "922" "923" "933" "934" "935"
## [331] "947" "948" "949" "950" "951" "963" "964" "965" "974" "975" "976"
## [342] "977"
## 
## $ubRev
## character(0)
## 
## $pos
## character(0)
## 
## $typeOfBill
## character(0)
lCodesNewbornsDRG <- makeList("Newborns/Neonates  MS-DRG")
## $valueSetName
## [1] "Newborns/Neonates  MS-DRG"
## 
## $summary
##      
##       Newborns/Neonates  MS-DRG
##   drg                         7
## 
## $cpt
## character(0)
## 
## $icd9cm
## character(0)
## 
## $icd9pcs
## character(0)
## 
## $drg
## [1] "789" "790" "791" "792" "793" "794" "795"
## 
## $ubRev
## character(0)
## 
## $pos
## character(0)
## 
## $typeOfBill
## character(0)
lCodesMaternityDiagnosis <- makeList("Maternity Diagnosis")
## $valueSetName
## [1] "Maternity Diagnosis"
## 
## $summary
##         
##          Maternity Diagnosis
##   icd9cm                1453
## 
## $cpt
## character(0)
## 
## $icd9cm
##    [1] "630"   "6310"  "631"   "6318"  "632"   "6330"  "63300" "633"  
##    [9] "63301" "6331"  "63310" "63311" "6332"  "63320" "63321" "6338" 
##   [17] "63380" "63381" "6339"  "63390" "63391" "6340"  "634"   "63400"
##   [25] "63401" "63402" "6341"  "63410" "63411" "63412" "6342"  "63420"
##   [33] "63421" "63422" "6343"  "63430" "63431" "63432" "6344"  "63440"
##   [41] "63441" "63442" "6345"  "63450" "63451" "63452" "6346"  "63460"
##   [49] "63461" "63462" "63470" "6347"  "63471" "63472" "63480" "6348" 
##   [57] "63481" "63482" "63490" "6349"  "63491" "63492" "6350"  "635"  
##   [65] "63500" "63501" "63502" "6351"  "63510" "63511" "63512" "6352" 
##   [73] "63520" "63521" "63522" "6353"  "63530" "63531" "63532" "6354" 
##   [81] "63540" "63541" "63542" "6355"  "63550" "63551" "63552" "6356" 
##   [89] "63560" "63561" "63562" "63570" "6357"  "63571" "63572" "63580"
##   [97] "6358"  "63581" "63582" "63590" "6359"  "63591" "63592" "6360" 
##  [105] "636"   "63600" "63601" "63602" "6361"  "63610" "63611" "63612"
##  [113] "6362"  "63620" "63621" "63622" "6363"  "63630" "63631" "63632"
##  [121] "6364"  "63640" "63641" "63642" "6365"  "63650" "63651" "63652"
##  [129] "6366"  "63660" "63661" "63662" "63670" "6367"  "63671" "63672"
##  [137] "63680" "6368"  "63681" "63682" "63690" "6369"  "63691" "63692"
##  [145] "6370"  "637"   "63700" "63701" "63702" "6371"  "63710" "63711"
##  [153] "63712" "6372"  "63720" "63721" "63722" "6373"  "63730" "63731"
##  [161] "63732" "6374"  "63740" "63741" "63742" "6375"  "63750" "63751"
##  [169] "63752" "6376"  "63760" "63761" "63762" "63770" "6377"  "63771"
##  [177] "63772" "63780" "6378"  "63781" "63782" "63790" "6379"  "63791"
##  [185] "63792" "6380"  "638"   "6381"  "6382"  "6383"  "6384"  "6385" 
##  [193] "6386"  "6387"  "6388"  "6389"  "639"   "6390"  "6391"  "6392" 
##  [201] "6393"  "6394"  "6395"  "6396"  "6398"  "6399"  "640"   "6400" 
##  [209] "64000" "64001" "64003" "6408"  "64080" "64081" "64083" "6409" 
##  [217] "64090" "64091" "64093" "641"   "6410"  "64100" "64101" "64103"
##  [225] "6411"  "64110" "64111" "64113" "6412"  "64120" "64121" "64123"
##  [233] "6413"  "64130" "64131" "64133" "6418"  "64180" "64181" "64183"
##  [241] "6419"  "64190" "64191" "64193" "6420"  "64200" "642"   "64201"
##  [249] "64202" "64203" "64204" "6421"  "64210" "64211" "64212" "64213"
##  [257] "64214" "6422"  "64220" "64221" "64222" "64223" "64224" "6423" 
##  [265] "64230" "64231" "64232" "64233" "64234" "6424"  "64240" "64241"
##  [273] "64242" "64243" "64244" "6425"  "64250" "64251" "64252" "64253"
##  [281] "64254" "6426"  "64260" "64261" "64262" "64263" "64264" "6427" 
##  [289] "64270" "64271" "64272" "64273" "64274" "6429"  "64290" "64291"
##  [297] "64292" "64293" "64294" "643"   "6430"  "64300" "64301" "64303"
##  [305] "6431"  "64310" "64311" "64313" "6432"  "64320" "64321" "64323"
##  [313] "6438"  "64380" "64381" "64383" "6439"  "64390" "64391" "64393"
##  [321] "644"   "6440"  "64400" "64403" "6441"  "64410" "64413" "6442" 
##  [329] "64420" "64421" "645"   "6451"  "64510" "64511" "64513" "6452" 
##  [337] "64520" "64521" "64523" "646"   "6460"  "64600" "64601" "64603"
##  [345] "6461"  "64610" "64611" "64612" "64613" "64614" "6462"  "64620"
##  [353] "64621" "64622" "64623" "64624" "6463"  "64630" "64631" "64633"
##  [361] "6464"  "64640" "64641" "64642" "64643" "64644" "6465"  "64650"
##  [369] "64651" "64652" "64653" "64654" "6466"  "64660" "64661" "64662"
##  [377] "64663" "64664" "6467"  "64670" "64671" "64673" "6468"  "64680"
##  [385] "64681" "64682" "64683" "64684" "6469"  "64690" "64691" "64693"
##  [393] "647"   "6470"  "64700" "64701" "64702" "64703" "64704" "6471" 
##  [401] "64710" "64711" "64712" "64713" "64714" "6472"  "64720" "64721"
##  [409] "64722" "64723" "64724" "6473"  "64730" "64731" "64732" "64733"
##  [417] "64734" "6474"  "64740" "64741" "64742" "64743" "64744" "6475" 
##  [425] "64750" "64751" "64752" "64753" "64754" "6476"  "64760" "64761"
##  [433] "64762" "64763" "64764" "6478"  "64780" "64781" "64782" "64783"
##  [441] "64784" "6479"  "64790" "64791" "64792" "64793" "64794" "6480" 
##  [449] "64800" "648"   "64801" "64802" "64803" "64804" "6481"  "64810"
##  [457] "64811" "64812" "64813" "64814" "6482"  "64820" "64821" "64822"
##  [465] "64823" "64824" "6483"  "64830" "64831" "64832" "64833" "64834"
##  [473] "6484"  "64840" "64841" "64842" "64843" "64844" "6485"  "64850"
##  [481] "64851" "64852" "64853" "64854" "6486"  "64860" "64861" "64862"
##  [489] "64863" "64864" "6487"  "64870" "64871" "64872" "64873" "64874"
##  [497] "6488"  "64880" "64881" "64882" "64883" "64884" "6489"  "64890"
##  [505] "64891" "64892" "64893" "64894" "649"   "6490"  "64900" "64901"
##  [513] "64902" "64903" "64904" "6491"  "64910" "64911" "64912" "64913"
##  [521] "64914" "6492"  "64920" "64921" "64922" "64923" "64924" "6493" 
##  [529] "64930" "64931" "64932" "64933" "64934" "6494"  "64940" "64941"
##  [537] "64942" "64943" "64944" "6495"  "64950" "64951" "64953" "6496" 
##  [545] "64960" "64961" "64962" "64963" "64964" "6497"  "64970" "64971"
##  [553] "64973" "6498"  "64981" "64982" "650"   "651"   "6510"  "65100"
##  [561] "65101" "65103" "6511"  "65110" "65111" "65113" "6512"  "65120"
##  [569] "65121" "65123" "6513"  "65130" "65131" "65133" "6514"  "65140"
##  [577] "65141" "65143" "6515"  "65150" "65151" "65153" "6516"  "65160"
##  [585] "65161" "65163" "6517"  "65170" "65171" "65173" "6518"  "65180"
##  [593] "65181" "65183" "6519"  "65190" "65191" "65193" "652"   "6520" 
##  [601] "65200" "65201" "65203" "6521"  "65210" "65211" "65213" "6522" 
##  [609] "65220" "65221" "65223" "6523"  "65230" "65231" "65233" "6524" 
##  [617] "65240" "65241" "65243" "6525"  "65250" "65251" "65253" "6526" 
##  [625] "65260" "65261" "65263" "6527"  "65270" "65271" "65273" "6528" 
##  [633] "65280" "65281" "65283" "6529"  "65290" "65291" "65293" "653"  
##  [641] "6530"  "65300" "65301" "65303" "6531"  "65310" "65311" "65313"
##  [649] "6532"  "65320" "65321" "65323" "6533"  "65330" "65331" "65333"
##  [657] "6534"  "65340" "65341" "65343" "6535"  "65350" "65351" "65353"
##  [665] "6536"  "65360" "65361" "65363" "6537"  "65370" "65371" "65373"
##  [673] "6538"  "65380" "65381" "65383" "6539"  "65390" "65391" "65393"
##  [681] "654"   "6540"  "65400" "65401" "65402" "65403" "65404" "6541" 
##  [689] "65410" "65411" "65412" "65413" "65414" "6542"  "65420" "65421"
##  [697] "65423" "6543"  "65430" "65431" "65432" "65433" "65434" "6544" 
##  [705] "65440" "65441" "65442" "65443" "65444" "6545"  "65450" "65451"
##  [713] "65452" "65453" "65454" "6546"  "65460" "65461" "65462" "65463"
##  [721] "65464" "6547"  "65470" "65471" "65472" "65473" "65474" "6548" 
##  [729] "65480" "65481" "65482" "65483" "65484" "6549"  "65490" "65491"
##  [737] "65492" "65493" "65494" "6550"  "65500" "655"   "65501" "65503"
##  [745] "6551"  "65510" "65511" "65513" "6552"  "65520" "65521" "65523"
##  [753] "6553"  "65530" "65531" "65533" "6554"  "65540" "65541" "65543"
##  [761] "6555"  "65550" "65551" "65553" "6556"  "65560" "65561" "65563"
##  [769] "6557"  "65570" "65571" "65573" "6558"  "65580" "65581" "65583"
##  [777] "6559"  "65590" "65591" "65593" "6560"  "65600" "656"   "65601"
##  [785] "65603" "6561"  "65610" "65611" "65613" "6562"  "65620" "65621"
##  [793] "65623" "6563"  "65630" "65631" "65633" "6564"  "65640" "65641"
##  [801] "65643" "6565"  "65650" "65651" "65653" "6566"  "65660" "65661"
##  [809] "65663" "6567"  "65670" "65671" "65673" "6568"  "65680" "65681"
##  [817] "65683" "6569"  "65690" "65691" "65693" "657"   "65700" "6570" 
##  [825] "65701" "65703" "6580"  "65800" "658"   "65801" "65803" "6581" 
##  [833] "65810" "65811" "65813" "6582"  "65820" "65821" "65823" "6583" 
##  [841] "65830" "65831" "65833" "6584"  "65840" "65841" "65843" "6588" 
##  [849] "65880" "65881" "65883" "6589"  "65890" "65891" "65893" "6590" 
##  [857] "65900" "659"   "65901" "65903" "6591"  "65910" "65911" "65913"
##  [865] "6592"  "65920" "65921" "65923" "6593"  "65930" "65931" "65933"
##  [873] "6594"  "65940" "65941" "65943" "6595"  "65950" "65951" "65953"
##  [881] "6596"  "65960" "65961" "65963" "6597"  "65970" "65971" "65973"
##  [889] "6598"  "65980" "65981" "65983" "6599"  "65990" "65991" "65993"
##  [897] "660"   "6600"  "66000" "66001" "66003" "6601"  "66010" "66011"
##  [905] "66013" "6602"  "66020" "66021" "66023" "6603"  "66030" "66031"
##  [913] "66033" "6604"  "66040" "66041" "66043" "6605"  "66050" "66051"
##  [921] "66053" "6606"  "66060" "66061" "66063" "6607"  "66070" "66071"
##  [929] "66073" "6608"  "66080" "66081" "66083" "6609"  "66090" "66091"
##  [937] "66093" "661"   "6610"  "66100" "66101" "66103" "6611"  "66110"
##  [945] "66111" "66113" "6612"  "66120" "66121" "66123" "6613"  "66130"
##  [953] "66131" "66133" "6614"  "66140" "66141" "66143" "6619"  "66190"
##  [961] "66191" "66193" "662"   "6620"  "66200" "66201" "66203" "6621" 
##  [969] "66210" "66211" "66213" "6622"  "66220" "66221" "66223" "6623" 
##  [977] "66230" "66231" "66233" "6630"  "66300" "663"   "66301" "66303"
##  [985] "66310" "6631"  "66311" "66313" "6632"  "66320" "66321" "66323"
##  [993] "6633"  "66330" "66331" "66333" "6634"  "66340" "66341" "66343"
## [1001] "6635"  "66350" "66351" "66353" "6636"  "66360" "66361" "66363"
## [1009] "6638"  "66380" "66381" "66383" "6639"  "66390" "66391" "66393"
## [1017] "6640"  "66400" "664"   "66401" "66404" "6641"  "66410" "66411"
## [1025] "66414" "6642"  "66420" "66421" "66424" "6643"  "66430" "66431"
## [1033] "66434" "6644"  "66440" "66441" "66444" "6645"  "66450" "66451"
## [1041] "66454" "6646"  "66460" "66461" "66464" "6648"  "66480" "66481"
## [1049] "66484" "6649"  "66490" "66491" "66494" "665"   "6650"  "66500"
## [1057] "66501" "66503" "6651"  "66510" "66511" "6652"  "66520" "66522"
## [1065] "66524" "6653"  "66530" "66531" "66534" "6654"  "66540" "66541"
## [1073] "66544" "6655"  "66550" "66551" "66554" "6656"  "66560" "66561"
## [1081] "66564" "6657"  "66570" "66571" "66572" "66574" "6658"  "66580"
## [1089] "66581" "66582" "66583" "66584" "6659"  "66590" "66591" "66592"
## [1097] "66593" "66594" "666"   "6660"  "66600" "66602" "66604" "6661" 
## [1105] "66610" "66612" "66614" "6662"  "66620" "66622" "66624" "6663" 
## [1113] "66630" "66632" "66634" "6670"  "667"   "66700" "66702" "66704"
## [1121] "6671"  "66710" "66712" "66714" "668"   "6680"  "66800" "66801"
## [1129] "66802" "66803" "66804" "6681"  "66810" "66811" "66812" "66813"
## [1137] "66814" "6682"  "66820" "66821" "66822" "66823" "66824" "6688" 
## [1145] "66880" "66881" "66882" "66883" "66884" "6689"  "66890" "66891"
## [1153] "66892" "66893" "66894" "6690"  "66900" "669"   "66901" "66902"
## [1161] "66903" "66904" "6691"  "66910" "66911" "66912" "66913" "66914"
## [1169] "6692"  "66920" "66921" "66922" "66923" "66924" "6693"  "66930"
## [1177] "66932" "66934" "6694"  "66940" "66941" "66942" "66943" "66944"
## [1185] "6695"  "66950" "66951" "6696"  "66960" "66961" "6697"  "66970"
## [1193] "66971" "6698"  "66980" "66981" "66982" "66983" "66984" "6699" 
## [1201] "66990" "66991" "66992" "66993" "66994" "670"   "6700"  "67000"
## [1209] "67002" "67004" "6701"  "67010" "67012" "67014" "6702"  "67020"
## [1217] "67022" "67024" "6703"  "67030" "67032" "67034" "6708"  "67080"
## [1225] "67082" "67084" "6710"  "67100" "671"   "67101" "67102" "67103"
## [1233] "67104" "6711"  "67110" "67111" "67112" "67113" "67114" "6712" 
## [1241] "67120" "67121" "67122" "67123" "67124" "6713"  "67130" "67131"
## [1249] "67133" "6714"  "67140" "67142" "67144" "6715"  "67150" "67151"
## [1257] "67152" "67153" "67154" "6718"  "67180" "67181" "67182" "67183"
## [1265] "67184" "6719"  "67190" "67191" "67192" "67193" "67194" "672"  
## [1273] "67200" "6720"  "67202" "67204" "6730"  "67300" "673"   "67301"
## [1281] "67302" "67303" "67304" "6731"  "67310" "67311" "67312" "67313"
## [1289] "67314" "6732"  "67320" "67321" "67322" "67323" "67324" "6733" 
## [1297] "67330" "67331" "67332" "67333" "67334" "67380" "6738"  "67381"
## [1305] "67382" "67383" "67384" "6740"  "67400" "674"   "67401" "67402"
## [1313] "67403" "67404" "6741"  "67410" "67412" "67414" "6742"  "67420"
## [1321] "67422" "67424" "6743"  "67430" "67432" "67434" "6744"  "67440"
## [1329] "67442" "67444" "6745"  "67450" "67451" "67452" "67453" "67454"
## [1337] "6748"  "67480" "67482" "67484" "6749"  "67490" "67492" "67494"
## [1345] "6750"  "67500" "675"   "67501" "67502" "67503" "67504" "6751" 
## [1353] "67510" "67511" "67512" "67513" "67514" "6752"  "67520" "67521"
## [1361] "67522" "67523" "67524" "6758"  "67580" "67581" "67582" "67583"
## [1369] "67584" "6759"  "67590" "67591" "67592" "67593" "67594" "676"  
## [1377] "6760"  "67600" "67601" "67602" "67603" "67604" "6761"  "67610"
## [1385] "67611" "67612" "67613" "67614" "6762"  "67620" "67621" "67622"
## [1393] "67623" "67624" "6763"  "67630" "67631" "67632" "67633" "67634"
## [1401] "6764"  "67640" "67641" "67642" "67643" "67644" "6765"  "67650"
## [1409] "67651" "67652" "67653" "67654" "6766"  "67660" "67661" "67662"
## [1417] "67663" "67664" "6768"  "67680" "67681" "67682" "67683" "67684"
## [1425] "6769"  "67690" "67691" "67692" "67693" "67694" "6780"  "67800"
## [1433] "678"   "67801" "67803" "6781"  "67810" "67811" "67813" "679"  
## [1441] "6790"  "67900" "67901" "67902" "67903" "67904" "6791"  "67910"
## [1449] "67911" "67912" "67913" "67914" "V240" 
## 
## $icd9pcs
## character(0)
## 
## $drg
## character(0)
## 
## $ubRev
## character(0)
## 
## $pos
## character(0)
## 
## $typeOfBill
## character(0)
lCodesMaternity <- makeList("Maternity")
## $valueSetName
## [1] "Maternity"
## 
## $summary
##             
##              Maternity
##   ubRev              9
##   typeOfBill        19
## 
## $cpt
## character(0)
## 
## $icd9cm
## character(0)
## 
## $icd9pcs
## character(0)
## 
## $drg
## character(0)
## 
## $ubRev
## [1] "0112" "0122" "0132" "0142" "0152" "0720" "0721" "0722" "0724"
## 
## $pos
## character(0)
## 
## $typeOfBill
##  [1] "840"  "841"  "842"  "843"  "844"  "845"  "847"  "848"  "084F" "084G"
## [11] "084H" "084I" "084J" "084K" "084M" "084O" "084X" "084Y" "084Z"
lCodesSurgery <- makeList("Surgery")
## $valueSetName
## [1] "Surgery"
## 
## $summary
##        
##         Surgery
##   ubRev       5
## 
## $cpt
## character(0)
## 
## $icd9cm
## character(0)
## 
## $icd9pcs
## character(0)
## 
## $drg
## character(0)
## 
## $ubRev
## [1] "0360" "0361" "0362" "0367" "0369"
## 
## $pos
## character(0)
## 
## $typeOfBill
## character(0)
lCodesObservation <- makeList("Observation")
## $valueSetName
## [1] "Observation"
## 
## $summary
##      
##       Observation
##   cpt           4
## 
## $cpt
## [1] "99217" "99218" "99219" "99220"
## 
## $icd9cm
## character(0)
## 
## $icd9pcs
## character(0)
## 
## $drg
## character(0)
## 
## $ubRev
## character(0)
## 
## $pos
## character(0)
## 
## $typeOfBill
## character(0)
lCodesED <- makeList("ED")
## $valueSetName
## [1] "ED"
## 
## $summary
##        
##         ED
##   cpt    5
##   ubRev  6
## 
## $cpt
## [1] "99281" "99282" "99283" "99284" "99285"
## 
## $icd9cm
## character(0)
## 
## $icd9pcs
## character(0)
## 
## $drg
## character(0)
## 
## $ubRev
## [1] "0450" "0451" "0452" "0456" "0459" "0981"
## 
## $pos
## character(0)
## 
## $typeOfBill
## character(0)
lCodesEDProcedureCode <- makeList("ED Procedure Code")
## $valueSetName
## [1] "ED Procedure Code"
## 
## $summary
##      
##       ED Procedure Code
##   cpt              5631
## 
## $cpt
##    [1] "10040" "10060" "10061" "10080" "10081" "10120" "10121" "10140"
##    [9] "10160" "10180" "11000" "11001" "11004" "11005" "11006" "11008"
##   [17] "11010" "11011" "11012" "11042" "11043" "11044" "11045" "11046"
##   [25] "11047" "11055" "11056" "11057" "11100" "11101" "11200" "11201"
##   [33] "11300" "11301" "11302" "11303" "11305" "11306" "11307" "11308"
##   [41] "11310" "11311" "11312" "11313" "11400" "11401" "11402" "11403"
##   [49] "11404" "11406" "11420" "11421" "11422" "11423" "11424" "11426"
##   [57] "11440" "11441" "11442" "11443" "11444" "11446" "11450" "11451"
##   [65] "11462" "11463" "11470" "11471" "11600" "11601" "11602" "11603"
##   [73] "11604" "11606" "11620" "11621" "11622" "11623" "11624" "11626"
##   [81] "11640" "11641" "11642" "11643" "11644" "11646" "11719" "11720"
##   [89] "11721" "11730" "11732" "11740" "11750" "11752" "11755" "11760"
##   [97] "11762" "11765" "11770" "11771" "11772" "11900" "11901" "11920"
##  [105] "11921" "11922" "11950" "11951" "11952" "11954" "11960" "11970"
##  [113] "11971" "11976" "11980" "11981" "11982" "11983" "12001" "12002"
##  [121] "12004" "12005" "12006" "12007" "12011" "12013" "12014" "12015"
##  [129] "12016" "12017" "12018" "12020" "12021" "12031" "12032" "12034"
##  [137] "12035" "12036" "12037" "12041" "12042" "12044" "12045" "12046"
##  [145] "12047" "12051" "12052" "12053" "12054" "12055" "12056" "12057"
##  [153] "13100" "13101" "13102" "13120" "13121" "13122" "13131" "13132"
##  [161] "13133" "13150" "13151" "13152" "13153" "13160" "14000" "14001"
##  [169] "14020" "14021" "14040" "14041" "14060" "14061" "14301" "14302"
##  [177] "14350" "15002" "15003" "15004" "15005" "15040" "15050" "15100"
##  [185] "15101" "15110" "15111" "15115" "15116" "15120" "15121" "15130"
##  [193] "15131" "15135" "15136" "15150" "15151" "15152" "15155" "15156"
##  [201] "15157" "15200" "15201" "15220" "15221" "15240" "15241" "15260"
##  [209] "15261" "15271" "15272" "15273" "15274" "15275" "15276" "15277"
##  [217] "15278" "15570" "15572" "15574" "15576" "15600" "15610" "15620"
##  [225] "15630" "15650" "15731" "15732" "15734" "15736" "15738" "15740"
##  [233] "15750" "15756" "15757" "15758" "15760" "15770" "15775" "15776"
##  [241] "15777" "15780" "15781" "15782" "15783" "15786" "15787" "15788"
##  [249] "15789" "15792" "15793" "15819" "15820" "15821" "15822" "15823"
##  [257] "15824" "15825" "15826" "15828" "15829" "15830" "15832" "15833"
##  [265] "15834" "15835" "15836" "15837" "15838" "15839" "15840" "15841"
##  [273] "15842" "15845" "15847" "15850" "15851" "15852" "15860" "15876"
##  [281] "15877" "15878" "15879" "15920" "15922" "15931" "15933" "15934"
##  [289] "15935" "15936" "15937" "15940" "15941" "15944" "15945" "15946"
##  [297] "15950" "15951" "15952" "15953" "15956" "15958" "15999" "16000"
##  [305] "16020" "16025" "16030" "16035" "16036" "17000" "17003" "17004"
##  [313] "17106" "17107" "17108" "17110" "17111" "17250" "17260" "17261"
##  [321] "17262" "17263" "17264" "17266" "17270" "17271" "17272" "17273"
##  [329] "17274" "17276" "17280" "17281" "17282" "17283" "17284" "17286"
##  [337] "17311" "17312" "17313" "17314" "17315" "17340" "17360" "17380"
##  [345] "17999" "19000" "19001" "19020" "19030" "19100" "19101" "19102"
##  [353] "19103" "19105" "19110" "19112" "19120" "19125" "19126" "19260"
##  [361] "19271" "19272" "19290" "19291" "19295" "19296" "19297" "19298"
##  [369] "19300" "19301" "19302" "19303" "19304" "19305" "19306" "19307"
##  [377] "19316" "19318" "19324" "19325" "19328" "19330" "19340" "19342"
##  [385] "19350" "19355" "19357" "19361" "19364" "19366" "19367" "19368"
##  [393] "19369" "19370" "19371" "19380" "19396" "19499" "20005" "20100"
##  [401] "20101" "20102" "20103" "20150" "20200" "20205" "20206" "20220"
##  [409] "20225" "20240" "20245" "20250" "20251" "20500" "20501" "20520"
##  [417] "20525" "20526" "20527" "20550" "20551" "20552" "20553" "20555"
##  [425] "20600" "20605" "20610" "20612" "20615" "20650" "20660" "20661"
##  [433] "20662" "20663" "20664" "20665" "20670" "20680" "20690" "20692"
##  [441] "20693" "20694" "20696" "20697" "20802" "20805" "20808" "20816"
##  [449] "20822" "20824" "20827" "20838" "20900" "20902" "20910" "20912"
##  [457] "20920" "20922" "20924" "20926" "20930" "20931" "20936" "20937"
##  [465] "20938" "20950" "20955" "20956" "20957" "20962" "20969" "20970"
##  [473] "20972" "20973" "20974" "20975" "20979" "20982" "20985" "20999"
##  [481] "21010" "21011" "21012" "21013" "21014" "21015" "21016" "21025"
##  [489] "21026" "21029" "21030" "21031" "21032" "21034" "21040" "21044"
##  [497] "21045" "21046" "21047" "21048" "21049" "21050" "21060" "21070"
##  [505] "21073" "21076" "21077" "21079" "21080" "21081" "21082" "21083"
##  [513] "21084" "21085" "21086" "21087" "21088" "21089" "21100" "21110"
##  [521] "21116" "21120" "21121" "21122" "21123" "21125" "21127" "21137"
##  [529] "21138" "21139" "21141" "21142" "21143" "21145" "21146" "21147"
##  [537] "21150" "21151" "21154" "21155" "21159" "21160" "21172" "21175"
##  [545] "21179" "21180" "21181" "21182" "21183" "21184" "21188" "21193"
##  [553] "21194" "21195" "21196" "21198" "21199" "21206" "21208" "21209"
##  [561] "21210" "21215" "21230" "21235" "21240" "21242" "21243" "21244"
##  [569] "21245" "21246" "21247" "21248" "21249" "21255" "21256" "21260"
##  [577] "21261" "21263" "21267" "21268" "21270" "21275" "21280" "21282"
##  [585] "21295" "21296" "21299" "21310" "21315" "21320" "21325" "21330"
##  [593] "21335" "21336" "21337" "21338" "21339" "21340" "21343" "21344"
##  [601] "21345" "21346" "21347" "21348" "21355" "21356" "21360" "21365"
##  [609] "21366" "21385" "21386" "21387" "21390" "21395" "21400" "21401"
##  [617] "21406" "21407" "21408" "21421" "21422" "21423" "21431" "21432"
##  [625] "21433" "21435" "21436" "21440" "21445" "21450" "21451" "21452"
##  [633] "21453" "21454" "21461" "21462" "21465" "21470" "21480" "21485"
##  [641] "21490" "21495" "21497" "21499" "21501" "21502" "21510" "21550"
##  [649] "21552" "21554" "21555" "21556" "21557" "21558" "21600" "21610"
##  [657] "21615" "21616" "21620" "21627" "21630" "21632" "21685" "21700"
##  [665] "21705" "21720" "21725" "21740" "21742" "21743" "21750" "21800"
##  [673] "21805" "21810" "21820" "21825" "21899" "21920" "21925" "21930"
##  [681] "21931" "21932" "21933" "21935" "21936" "22010" "22015" "22100"
##  [689] "22101" "22102" "22103" "22110" "22112" "22114" "22116" "22206"
##  [697] "22207" "22208" "22210" "22212" "22214" "22216" "22220" "22222"
##  [705] "22224" "22226" "22305" "22310" "22315" "22318" "22319" "22325"
##  [713] "22326" "22327" "22328" "22505" "22520" "22521" "22522" "22523"
##  [721] "22524" "22525" "22526" "22527" "22532" "22533" "22534" "22548"
##  [729] "22551" "22552" "22554" "22556" "22558" "22585" "22586" "22590"
##  [737] "22595" "22600" "22610" "22612" "22614" "22630" "22632" "22633"
##  [745] "22634" "22800" "22802" "22804" "22808" "22810" "22812" "22818"
##  [753] "22819" "22830" "22840" "22841" "22842" "22843" "22844" "22845"
##  [761] "22846" "22847" "22848" "22849" "22850" "22851" "22852" "22855"
##  [769] "22856" "22857" "22861" "22862" "22864" "22865" "22899" "22900"
##  [777] "22901" "22902" "22903" "22904" "22905" "22999" "23000" "23020"
##  [785] "23030" "23031" "23035" "23040" "23044" "23065" "23066" "23071"
##  [793] "23073" "23075" "23076" "23077" "23078" "23100" "23101" "23105"
##  [801] "23106" "23107" "23120" "23125" "23130" "23140" "23145" "23146"
##  [809] "23150" "23155" "23156" "23170" "23172" "23174" "23180" "23182"
##  [817] "23184" "23190" "23195" "23200" "23210" "23220" "23330" "23331"
##  [825] "23332" "23350" "23395" "23397" "23400" "23405" "23406" "23410"
##  [833] "23412" "23415" "23420" "23430" "23440" "23450" "23455" "23460"
##  [841] "23462" "23465" "23466" "23470" "23472" "23473" "23474" "23480"
##  [849] "23485" "23490" "23491" "23500" "23505" "23515" "23520" "23525"
##  [857] "23530" "23532" "23540" "23545" "23550" "23552" "23570" "23575"
##  [865] "23585" "23600" "23605" "23615" "23616" "23620" "23625" "23630"
##  [873] "23650" "23655" "23660" "23665" "23670" "23675" "23680" "23700"
##  [881] "23800" "23802" "23900" "23920" "23921" "23929" "23930" "23931"
##  [889] "23935" "24000" "24006" "24065" "24066" "24071" "24073" "24075"
##  [897] "24076" "24077" "24079" "24100" "24101" "24102" "24105" "24110"
##  [905] "24115" "24116" "24120" "24125" "24126" "24130" "24134" "24136"
##  [913] "24138" "24140" "24145" "24147" "24149" "24150" "24152" "24155"
##  [921] "24160" "24164" "24200" "24201" "24220" "24300" "24301" "24305"
##  [929] "24310" "24320" "24330" "24331" "24332" "24340" "24341" "24342"
##  [937] "24343" "24344" "24345" "24346" "24357" "24358" "24359" "24360"
##  [945] "24361" "24362" "24363" "24365" "24366" "24370" "24371" "24400"
##  [953] "24410" "24420" "24430" "24435" "24470" "24495" "24498" "24500"
##  [961] "24505" "24515" "24516" "24530" "24535" "24538" "24545" "24546"
##  [969] "24560" "24565" "24566" "24575" "24576" "24577" "24579" "24582"
##  [977] "24586" "24587" "24600" "24605" "24615" "24620" "24635" "24640"
##  [985] "24650" "24655" "24665" "24666" "24670" "24675" "24685" "24800"
##  [993] "24802" "24900" "24920" "24925" "24930" "24931" "24935" "24940"
## [1001] "24999" "25000" "25001" "25020" "25023" "25024" "25025" "25028"
## [1009] "25031" "25035" "25040" "25065" "25066" "25071" "25073" "25075"
## [1017] "25076" "25077" "25078" "25085" "25100" "25101" "25105" "25107"
## [1025] "25109" "25110" "25111" "25112" "25115" "25116" "25118" "25119"
## [1033] "25120" "25125" "25126" "25130" "25135" "25136" "25145" "25150"
## [1041] "25151" "25170" "25210" "25215" "25230" "25240" "25246" "25248"
## [1049] "25250" "25251" "25259" "25260" "25263" "25265" "25270" "25272"
## [1057] "25274" "25275" "25280" "25290" "25295" "25300" "25301" "25310"
## [1065] "25312" "25315" "25316" "25320" "25332" "25335" "25337" "25350"
## [1073] "25355" "25360" "25365" "25370" "25375" "25390" "25391" "25392"
## [1081] "25393" "25394" "25400" "25405" "25415" "25420" "25425" "25426"
## [1089] "25430" "25431" "25440" "25441" "25442" "25443" "25444" "25445"
## [1097] "25446" "25447" "25449" "25450" "25455" "25490" "25491" "25492"
## [1105] "25500" "25505" "25515" "25520" "25525" "25526" "25530" "25535"
## [1113] "25545" "25560" "25565" "25574" "25575" "25600" "25605" "25606"
## [1121] "25607" "25608" "25609" "25622" "25624" "25628" "25630" "25635"
## [1129] "25645" "25650" "25651" "25652" "25660" "25670" "25671" "25675"
## [1137] "25676" "25680" "25685" "25690" "25695" "25800" "25805" "25810"
## [1145] "25820" "25825" "25830" "25900" "25905" "25907" "25909" "25915"
## [1153] "25920" "25922" "25924" "25927" "25929" "25931" "25999" "26010"
## [1161] "26011" "26020" "26025" "26030" "26034" "26035" "26037" "26040"
## [1169] "26045" "26055" "26060" "26070" "26075" "26080" "26100" "26105"
## [1177] "26110" "26111" "26113" "26115" "26116" "26117" "26118" "26121"
## [1185] "26123" "26125" "26130" "26135" "26140" "26145" "26160" "26170"
## [1193] "26180" "26185" "26200" "26205" "26210" "26215" "26230" "26235"
## [1201] "26236" "26250" "26260" "26262" "26320" "26340" "26341" "26350"
## [1209] "26352" "26356" "26357" "26358" "26370" "26372" "26373" "26390"
## [1217] "26392" "26410" "26412" "26415" "26416" "26418" "26420" "26426"
## [1225] "26428" "26432" "26433" "26434" "26437" "26440" "26442" "26445"
## [1233] "26449" "26450" "26455" "26460" "26471" "26474" "26476" "26477"
## [1241] "26478" "26479" "26480" "26483" "26485" "26489" "26490" "26492"
## [1249] "26494" "26496" "26497" "26498" "26499" "26500" "26502" "26508"
## [1257] "26510" "26516" "26517" "26518" "26520" "26525" "26530" "26531"
## [1265] "26535" "26536" "26540" "26541" "26542" "26545" "26546" "26548"
## [1273] "26550" "26551" "26553" "26554" "26555" "26556" "26560" "26561"
## [1281] "26562" "26565" "26567" "26568" "26580" "26587" "26590" "26591"
## [1289] "26593" "26596" "26600" "26605" "26607" "26608" "26615" "26641"
## [1297] "26645" "26650" "26665" "26670" "26675" "26676" "26685" "26686"
## [1305] "26700" "26705" "26706" "26715" "26720" "26725" "26727" "26735"
## [1313] "26740" "26742" "26746" "26750" "26755" "26756" "26765" "26770"
## [1321] "26775" "26776" "26785" "26820" "26841" "26842" "26843" "26844"
## [1329] "26850" "26852" "26860" "26861" "26862" "26863" "26910" "26951"
## [1337] "26952" "26989" "26990" "26991" "26992" "27000" "27001" "27003"
## [1345] "27005" "27006" "27025" "27027" "27030" "27033" "27035" "27036"
## [1353] "27040" "27041" "27043" "27045" "27047" "27048" "27049" "27050"
## [1361] "27052" "27054" "27057" "27059" "27060" "27062" "27065" "27066"
## [1369] "27067" "27070" "27071" "27075" "27076" "27077" "27078" "27080"
## [1377] "27086" "27087" "27090" "27091" "27093" "27095" "27096" "27097"
## [1385] "27098" "27100" "27105" "27110" "27111" "27120" "27122" "27125"
## [1393] "27130" "27132" "27134" "27137" "27138" "27140" "27146" "27147"
## [1401] "27151" "27156" "27158" "27161" "27165" "27170" "27175" "27176"
## [1409] "27177" "27178" "27179" "27181" "27185" "27187" "27193" "27194"
## [1417] "27200" "27202" "27215" "27216" "27217" "27218" "27220" "27222"
## [1425] "27226" "27227" "27228" "27230" "27232" "27235" "27236" "27238"
## [1433] "27240" "27244" "27245" "27246" "27248" "27250" "27252" "27253"
## [1441] "27254" "27256" "27257" "27258" "27259" "27265" "27266" "27267"
## [1449] "27268" "27269" "27275" "27280" "27282" "27284" "27286" "27290"
## [1457] "27295" "27299" "27301" "27303" "27305" "27306" "27307" "27310"
## [1465] "27323" "27324" "27325" "27326" "27327" "27328" "27329" "27330"
## [1473] "27331" "27332" "27333" "27334" "27335" "27337" "27339" "27340"
## [1481] "27345" "27347" "27350" "27355" "27356" "27357" "27358" "27360"
## [1489] "27364" "27365" "27370" "27372" "27380" "27381" "27385" "27386"
## [1497] "27390" "27391" "27392" "27393" "27394" "27395" "27396" "27397"
## [1505] "27400" "27403" "27405" "27407" "27409" "27412" "27415" "27416"
## [1513] "27418" "27420" "27422" "27424" "27425" "27427" "27428" "27429"
## [1521] "27430" "27435" "27437" "27438" "27440" "27441" "27442" "27443"
## [1529] "27445" "27446" "27447" "27448" "27450" "27454" "27455" "27457"
## [1537] "27465" "27466" "27468" "27470" "27472" "27475" "27477" "27479"
## [1545] "27485" "27486" "27487" "27488" "27495" "27496" "27497" "27498"
## [1553] "27499" "27500" "27501" "27502" "27503" "27506" "27507" "27508"
## [1561] "27509" "27510" "27511" "27513" "27514" "27516" "27517" "27519"
## [1569] "27520" "27524" "27530" "27532" "27535" "27536" "27538" "27540"
## [1577] "27550" "27552" "27556" "27557" "27558" "27560" "27562" "27566"
## [1585] "27570" "27580" "27590" "27591" "27592" "27594" "27596" "27598"
## [1593] "27599" "27600" "27601" "27602" "27603" "27604" "27605" "27606"
## [1601] "27607" "27610" "27612" "27613" "27614" "27615" "27616" "27618"
## [1609] "27619" "27620" "27625" "27626" "27630" "27632" "27634" "27635"
## [1617] "27637" "27638" "27640" "27641" "27645" "27646" "27647" "27648"
## [1625] "27650" "27652" "27654" "27656" "27658" "27659" "27664" "27665"
## [1633] "27675" "27676" "27680" "27681" "27685" "27686" "27687" "27690"
## [1641] "27691" "27692" "27695" "27696" "27698" "27700" "27702" "27703"
## [1649] "27704" "27705" "27707" "27709" "27712" "27715" "27720" "27722"
## [1657] "27724" "27725" "27726" "27727" "27730" "27732" "27734" "27740"
## [1665] "27742" "27745" "27750" "27752" "27756" "27758" "27759" "27760"
## [1673] "27762" "27766" "27767" "27768" "27769" "27780" "27781" "27784"
## [1681] "27786" "27788" "27792" "27808" "27810" "27814" "27816" "27818"
## [1689] "27822" "27823" "27824" "27825" "27826" "27827" "27828" "27829"
## [1697] "27830" "27831" "27832" "27840" "27842" "27846" "27848" "27860"
## [1705] "27870" "27871" "27880" "27881" "27882" "27884" "27886" "27888"
## [1713] "27889" "27892" "27893" "27894" "27899" "28001" "28002" "28003"
## [1721] "28005" "28008" "28010" "28011" "28020" "28022" "28024" "28035"
## [1729] "28039" "28041" "28043" "28045" "28046" "28047" "28050" "28052"
## [1737] "28054" "28055" "28060" "28062" "28070" "28072" "28080" "28086"
## [1745] "28088" "28090" "28092" "28100" "28102" "28103" "28104" "28106"
## [1753] "28107" "28108" "28110" "28111" "28112" "28113" "28114" "28116"
## [1761] "28118" "28119" "28120" "28122" "28124" "28126" "28130" "28140"
## [1769] "28150" "28153" "28160" "28171" "28173" "28175" "28190" "28192"
## [1777] "28193" "28200" "28202" "28208" "28210" "28220" "28222" "28225"
## [1785] "28226" "28230" "28232" "28234" "28238" "28240" "28250" "28260"
## [1793] "28261" "28262" "28264" "28270" "28272" "28280" "28285" "28286"
## [1801] "28288" "28289" "28290" "28292" "28293" "28294" "28296" "28297"
## [1809] "28298" "28299" "28300" "28302" "28304" "28305" "28306" "28307"
## [1817] "28308" "28309" "28310" "28312" "28313" "28315" "28320" "28322"
## [1825] "28340" "28341" "28344" "28345" "28360" "28400" "28405" "28406"
## [1833] "28415" "28420" "28430" "28435" "28436" "28445" "28446" "28450"
## [1841] "28455" "28456" "28465" "28470" "28475" "28476" "28485" "28490"
## [1849] "28495" "28496" "28505" "28510" "28515" "28525" "28530" "28531"
## [1857] "28540" "28545" "28546" "28555" "28570" "28575" "28576" "28585"
## [1865] "28600" "28605" "28606" "28615" "28630" "28635" "28636" "28645"
## [1873] "28660" "28665" "28666" "28675" "28705" "28715" "28725" "28730"
## [1881] "28735" "28737" "28740" "28750" "28755" "28760" "28800" "28805"
## [1889] "28810" "28820" "28825" "28890" "28899" "29000" "29010" "29015"
## [1897] "29020" "29025" "29035" "29040" "29044" "29046" "29049" "29055"
## [1905] "29058" "29065" "29075" "29085" "29086" "29105" "29125" "29126"
## [1913] "29130" "29131" "29200" "29240" "29260" "29280" "29305" "29325"
## [1921] "29345" "29355" "29358" "29365" "29405" "29425" "29435" "29440"
## [1929] "29445" "29450" "29505" "29515" "29520" "29530" "29540" "29550"
## [1937] "29580" "29581" "29582" "29583" "29584" "29590" "29700" "29705"
## [1945] "29710" "29715" "29720" "29730" "29740" "29750" "29799" "29800"
## [1953] "29804" "29805" "29806" "29807" "29819" "29820" "29821" "29822"
## [1961] "29823" "29824" "29825" "29826" "29827" "29828" "29830" "29834"
## [1969] "29835" "29836" "29837" "29838" "29840" "29843" "29844" "29845"
## [1977] "29846" "29847" "29848" "29850" "29851" "29855" "29856" "29860"
## [1985] "29861" "29862" "29863" "29866" "29867" "29868" "29870" "29871"
## [1993] "29873" "29874" "29875" "29876" "29877" "29879" "29880" "29881"
## [2001] "29882" "29883" "29884" "29885" "29886" "29887" "29888" "29889"
## [2009] "29891" "29892" "29893" "29894" "29895" "29897" "29898" "29899"
## [2017] "29900" "29901" "29902" "29904" "29905" "29906" "29907" "29914"
## [2025] "29915" "29916" "29999" "30000" "30020" "30100" "30110" "30115"
## [2033] "30117" "30118" "30120" "30124" "30125" "30130" "30140" "30150"
## [2041] "30160" "30200" "30210" "30220" "30300" "30310" "30320" "30400"
## [2049] "30410" "30420" "30430" "30435" "30450" "30460" "30462" "30465"
## [2057] "30520" "30540" "30545" "30560" "30580" "30600" "30620" "30630"
## [2065] "30801" "30802" "30901" "30903" "30905" "30906" "30915" "30920"
## [2073] "30930" "30999" "31000" "31002" "31020" "31030" "31032" "31040"
## [2081] "31050" "31051" "31070" "31075" "31080" "31081" "31084" "31085"
## [2089] "31086" "31087" "31090" "31200" "31201" "31205" "31225" "31230"
## [2097] "31231" "31233" "31235" "31237" "31238" "31239" "31240" "31254"
## [2105] "31255" "31256" "31267" "31276" "31287" "31288" "31290" "31291"
## [2113] "31292" "31293" "31294" "31295" "31296" "31297" "31299" "31300"
## [2121] "31320" "31360" "31365" "31367" "31368" "31370" "31375" "31380"
## [2129] "31382" "31390" "31395" "31400" "31420" "31500" "31502" "31505"
## [2137] "31510" "31511" "31512" "31513" "31515" "31520" "31525" "31526"
## [2145] "31527" "31528" "31529" "31530" "31531" "31535" "31536" "31540"
## [2153] "31541" "31545" "31546" "31560" "31561" "31570" "31571" "31575"
## [2161] "31576" "31577" "31578" "31579" "31580" "31582" "31584" "31587"
## [2169] "31588" "31590" "31595" "31599" "31600" "31601" "31603" "31605"
## [2177] "31610" "31611" "31612" "31613" "31614" "31615" "31620" "31622"
## [2185] "31623" "31624" "31625" "31626" "31627" "31628" "31629" "31630"
## [2193] "31631" "31632" "31633" "31634" "31635" "31636" "31637" "31638"
## [2201] "31640" "31641" "31643" "31645" "31646" "31647" "31648" "31649"
## [2209] "31651" "31656" "31660" "31661" "31715" "31717" "31720" "31725"
## [2217] "31730" "31750" "31755" "31760" "31766" "31770" "31775" "31780"
## [2225] "31781" "31785" "31786" "31800" "31805" "31820" "31825" "31830"
## [2233] "31899" "32035" "32036" "32096" "32097" "32098" "32100" "32110"
## [2241] "32120" "32124" "32140" "32141" "32150" "32151" "32160" "32200"
## [2249] "32201" "32215" "32220" "32225" "32310" "32320" "32400" "32405"
## [2257] "32420" "32421" "32422" "32440" "32442" "32445" "32480" "32482"
## [2265] "32484" "32486" "32488" "32491" "32501" "32503" "32504" "32505"
## [2273] "32506" "32507" "32540" "32550" "32551" "32552" "32553" "32554"
## [2281] "32555" "32556" "32557" "32560" "32561" "32562" "32601" "32604"
## [2289] "32606" "32607" "32608" "32609" "32650" "32651" "32652" "32653"
## [2297] "32654" "32655" "32656" "32658" "32659" "32661" "32662" "32663"
## [2305] "32664" "32665" "32666" "32667" "32668" "32669" "32670" "32671"
## [2313] "32672" "32673" "32674" "32701" "32800" "32810" "32815" "32820"
## [2321] "32850" "32851" "32852" "32853" "32854" "32855" "32856" "32900"
## [2329] "32905" "32906" "32940" "32960" "32997" "32998" "32999" "33010"
## [2337] "33011" "33015" "33020" "33025" "33030" "33031" "33050" "33120"
## [2345] "33130" "33140" "33141" "33202" "33203" "33206" "33207" "33208"
## [2353] "33210" "33211" "33212" "33213" "33214" "33215" "33216" "33217"
## [2361] "33218" "33220" "33221" "33222" "33223" "33224" "33225" "33226"
## [2369] "33227" "33228" "33229" "33230" "33231" "33233" "33234" "33235"
## [2377] "33236" "33237" "33238" "33240" "33241" "33243" "33244" "33249"
## [2385] "33250" "33251" "33254" "33255" "33256" "33257" "33258" "33259"
## [2393] "33261" "33262" "33263" "33264" "33265" "33266" "33282" "33284"
## [2401] "33300" "33305" "33310" "33315" "33320" "33321" "33322" "33330"
## [2409] "33332" "33335" "33361" "33362" "33363" "33364" "33365" "33367"
## [2417] "33368" "33369" "33400" "33401" "33403" "33404" "33405" "33406"
## [2425] "33410" "33411" "33412" "33413" "33414" "33415" "33416" "33417"
## [2433] "33420" "33422" "33425" "33426" "33427" "33430" "33460" "33463"
## [2441] "33464" "33465" "33468" "33470" "33471" "33472" "33474" "33475"
## [2449] "33476" "33478" "33496" "33500" "33501" "33502" "33503" "33504"
## [2457] "33505" "33506" "33507" "33508" "33510" "33511" "33512" "33513"
## [2465] "33514" "33516" "33517" "33518" "33519" "33521" "33522" "33523"
## [2473] "33530" "33533" "33534" "33535" "33536" "33542" "33545" "33548"
## [2481] "33572" "33600" "33602" "33606" "33608" "33610" "33611" "33612"
## [2489] "33615" "33617" "33619" "33620" "33621" "33622" "33641" "33645"
## [2497] "33647" "33660" "33665" "33670" "33675" "33676" "33677" "33681"
## [2505] "33684" "33688" "33690" "33692" "33694" "33697" "33702" "33710"
## [2513] "33720" "33722" "33724" "33726" "33730" "33732" "33735" "33736"
## [2521] "33737" "33750" "33755" "33762" "33764" "33766" "33767" "33768"
## [2529] "33770" "33771" "33774" "33775" "33776" "33777" "33778" "33779"
## [2537] "33780" "33781" "33782" "33783" "33786" "33788" "33800" "33802"
## [2545] "33803" "33813" "33814" "33820" "33822" "33824" "33840" "33845"
## [2553] "33851" "33852" "33853" "33860" "33863" "33864" "33870" "33875"
## [2561] "33877" "33880" "33881" "33883" "33884" "33886" "33889" "33891"
## [2569] "33910" "33915" "33916" "33917" "33920" "33922" "33924" "33925"
## [2577] "33926" "33930" "33933" "33935" "33940" "33944" "33945" "33960"
## [2585] "33961" "33967" "33968" "33970" "33971" "33973" "33974" "33975"
## [2593] "33976" "33977" "33978" "33979" "33980" "33981" "33982" "33983"
## [2601] "33990" "33991" "33992" "33993" "33999" "34001" "34051" "34101"
## [2609] "34111" "34151" "34201" "34203" "34401" "34421" "34451" "34471"
## [2617] "34490" "34501" "34502" "34510" "34520" "34530" "34800" "34802"
## [2625] "34803" "34804" "34805" "34806" "34808" "34812" "34813" "34820"
## [2633] "34825" "34826" "34830" "34831" "34832" "34833" "34834" "34900"
## [2641] "35001" "35002" "35005" "35011" "35013" "35021" "35022" "35045"
## [2649] "35081" "35082" "35091" "35092" "35102" "35103" "35111" "35112"
## [2657] "35121" "35122" "35131" "35132" "35141" "35142" "35151" "35152"
## [2665] "35180" "35182" "35184" "35188" "35189" "35190" "35201" "35206"
## [2673] "35207" "35211" "35216" "35221" "35226" "35231" "35236" "35241"
## [2681] "35246" "35251" "35256" "35261" "35266" "35271" "35276" "35281"
## [2689] "35286" "35301" "35302" "35303" "35304" "35305" "35306" "35311"
## [2697] "35321" "35331" "35341" "35351" "35355" "35361" "35363" "35371"
## [2705] "35372" "35390" "35400" "35450" "35452" "35458" "35460" "35471"
## [2713] "35472" "35475" "35476" "35500" "35501" "35506" "35508" "35509"
## [2721] "35510" "35511" "35512" "35515" "35516" "35518" "35521" "35522"
## [2729] "35523" "35525" "35526" "35531" "35533" "35535" "35536" "35537"
## [2737] "35538" "35539" "35540" "35556" "35558" "35560" "35563" "35565"
## [2745] "35566" "35570" "35571" "35572" "35583" "35585" "35587" "35600"
## [2753] "35601" "35606" "35612" "35616" "35621" "35623" "35626" "35631"
## [2761] "35632" "35633" "35634" "35636" "35637" "35638" "35642" "35645"
## [2769] "35646" "35647" "35650" "35654" "35656" "35661" "35663" "35665"
## [2777] "35666" "35671" "35681" "35682" "35683" "35685" "35686" "35691"
## [2785] "35693" "35694" "35695" "35697" "35700" "35701" "35721" "35741"
## [2793] "35761" "35800" "35820" "35840" "35860" "35870" "35875" "35876"
## [2801] "35879" "35881" "35883" "35884" "35901" "35903" "35905" "35907"
## [2809] "36000" "36002" "36005" "36010" "36011" "36012" "36013" "36014"
## [2817] "36015" "36100" "36120" "36140" "36147" "36148" "36160" "36200"
## [2825] "36215" "36216" "36217" "36218" "36221" "36222" "36223" "36224"
## [2833] "36225" "36226" "36227" "36228" "36245" "36246" "36247" "36248"
## [2841] "36251" "36252" "36253" "36254" "36260" "36261" "36262" "36299"
## [2849] "36400" "36405" "36406" "36410" "36415" "36416" "36420" "36425"
## [2857] "36430" "36440" "36450" "36455" "36460" "36468" "36469" "36470"
## [2865] "36471" "36475" "36476" "36478" "36479" "36481" "36500" "36510"
## [2873] "36511" "36512" "36513" "36514" "36515" "36516" "36522" "36555"
## [2881] "36556" "36557" "36558" "36560" "36561" "36563" "36565" "36566"
## [2889] "36568" "36569" "36570" "36571" "36575" "36576" "36578" "36580"
## [2897] "36581" "36582" "36583" "36584" "36585" "36589" "36590" "36591"
## [2905] "36592" "36593" "36595" "36596" "36597" "36598" "36600" "36620"
## [2913] "36625" "36640" "36660" "36680" "36800" "36810" "36815" "36818"
## [2921] "36819" "36820" "36821" "36822" "36823" "36825" "36830" "36831"
## [2929] "36832" "36833" "36835" "36838" "36860" "36861" "36870" "37140"
## [2937] "37145" "37160" "37180" "37181" "37182" "37183" "37184" "37185"
## [2945] "37186" "37187" "37188" "37191" "37192" "37193" "37195" "37197"
## [2953] "37200" "37201" "37202" "37203" "37204" "37205" "37206" "37207"
## [2961] "37208" "37209" "37210" "37211" "37212" "37213" "37214" "37215"
## [2969] "37216" "37220" "37221" "37222" "37223" "37224" "37225" "37226"
## [2977] "37227" "37228" "37229" "37230" "37231" "37232" "37233" "37234"
## [2985] "37235" "37250" "37251" "37500" "37501" "37565" "37600" "37605"
## [2993] "37606" "37607" "37609" "37615" "37616" "37617" "37618" "37619"
## [3001] "37650" "37660" "37700" "37718" "37722" "37735" "37760" "37761"
## [3009] "37765" "37766" "37780" "37785" "37788" "37790" "37799" "38100"
## [3017] "38101" "38102" "38115" "38120" "38129" "38200" "38204" "38205"
## [3025] "38206" "38207" "38208" "38209" "38210" "38211" "38212" "38213"
## [3033] "38214" "38215" "38220" "38221" "38230" "38232" "38240" "38241"
## [3041] "38242" "38243" "38300" "38305" "38308" "38380" "38381" "38382"
## [3049] "38500" "38505" "38510" "38520" "38525" "38530" "38542" "38550"
## [3057] "38555" "38562" "38564" "38570" "38571" "38572" "38589" "38700"
## [3065] "38720" "38724" "38740" "38745" "38746" "38747" "38760" "38765"
## [3073] "38770" "38780" "38790" "38792" "38794" "38900" "38999" "39000"
## [3081] "39010" "39200" "39220" "39400" "39499" "39501" "39503" "39540"
## [3089] "39541" "39545" "39560" "39561" "39599" "40490" "40500" "40510"
## [3097] "40520" "40525" "40527" "40530" "40650" "40652" "40654" "40700"
## [3105] "40701" "40702" "40720" "40761" "40799" "40800" "40801" "40804"
## [3113] "40805" "40806" "40808" "40810" "40812" "40814" "40816" "40818"
## [3121] "40819" "40820" "40830" "40831" "40840" "40842" "40843" "40844"
## [3129] "40845" "40899" "41000" "41005" "41006" "41007" "41008" "41009"
## [3137] "41010" "41015" "41016" "41017" "41018" "41019" "41100" "41105"
## [3145] "41108" "41110" "41112" "41113" "41114" "41115" "41116" "41120"
## [3153] "41130" "41135" "41140" "41145" "41150" "41153" "41155" "41250"
## [3161] "41251" "41252" "41500" "41510" "41512" "41520" "41530" "41599"
## [3169] "41800" "41805" "41806" "41820" "41821" "41822" "41823" "41825"
## [3177] "41826" "41827" "41828" "41830" "41850" "41870" "41872" "41874"
## [3185] "41899" "42000" "42100" "42104" "42106" "42107" "42120" "42140"
## [3193] "42145" "42160" "42180" "42182" "42200" "42205" "42210" "42215"
## [3201] "42220" "42225" "42226" "42227" "42235" "42260" "42280" "42281"
## [3209] "42299" "42300" "42305" "42310" "42320" "42330" "42335" "42340"
## [3217] "42400" "42405" "42408" "42409" "42410" "42415" "42420" "42425"
## [3225] "42426" "42440" "42450" "42500" "42505" "42507" "42508" "42509"
## [3233] "42510" "42550" "42600" "42650" "42660" "42665" "42699" "42700"
## [3241] "42720" "42725" "42800" "42802" "42804" "42806" "42808" "42809"
## [3249] "42810" "42815" "42820" "42821" "42825" "42826" "42830" "42831"
## [3257] "42835" "42836" "42842" "42844" "42845" "42860" "42870" "42890"
## [3265] "42892" "42894" "42900" "42950" "42953" "42955" "42960" "42961"
## [3273] "42962" "42970" "42971" "42972" "42999" "43020" "43030" "43045"
## [3281] "43100" "43101" "43107" "43108" "43112" "43113" "43116" "43117"
## [3289] "43118" "43121" "43122" "43123" "43124" "43130" "43135" "43200"
## [3297] "43201" "43202" "43204" "43205" "43206" "43215" "43216" "43217"
## [3305] "43219" "43220" "43226" "43227" "43228" "43231" "43232" "43234"
## [3313] "43235" "43236" "43237" "43238" "43239" "43240" "43241" "43242"
## [3321] "43243" "43244" "43245" "43246" "43247" "43248" "43249" "43250"
## [3329] "43251" "43252" "43255" "43256" "43257" "43258" "43259" "43260"
## [3337] "43261" "43262" "43263" "43264" "43265" "43267" "43268" "43269"
## [3345] "43271" "43272" "43273" "43279" "43280" "43281" "43282" "43283"
## [3353] "43289" "43300" "43305" "43310" "43312" "43313" "43314" "43320"
## [3361] "43325" "43327" "43328" "43330" "43331" "43332" "43333" "43334"
## [3369] "43335" "43336" "43337" "43338" "43340" "43341" "43350" "43351"
## [3377] "43352" "43360" "43361" "43400" "43401" "43405" "43410" "43415"
## [3385] "43420" "43425" "43450" "43453" "43456" "43458" "43460" "43496"
## [3393] "43499" "43500" "43501" "43502" "43510" "43520" "43605" "43610"
## [3401] "43611" "43620" "43621" "43622" "43631" "43632" "43633" "43634"
## [3409] "43635" "43640" "43641" "43644" "43645" "43647" "43648" "43651"
## [3417] "43652" "43653" "43659" "43752" "43753" "43754" "43755" "43756"
## [3425] "43757" "43760" "43761" "43770" "43771" "43772" "43773" "43774"
## [3433] "43775" "43800" "43810" "43820" "43825" "43830" "43831" "43832"
## [3441] "43840" "43842" "43843" "43845" "43846" "43847" "43848" "43850"
## [3449] "43855" "43860" "43865" "43870" "43880" "43881" "43882" "43886"
## [3457] "43887" "43888" "43999" "44005" "44010" "44015" "44020" "44021"
## [3465] "44025" "44050" "44055" "44100" "44110" "44111" "44120" "44121"
## [3473] "44125" "44126" "44127" "44128" "44130" "44132" "44133" "44135"
## [3481] "44136" "44137" "44139" "44140" "44141" "44143" "44144" "44145"
## [3489] "44146" "44147" "44150" "44151" "44155" "44156" "44157" "44158"
## [3497] "44160" "44180" "44186" "44187" "44188" "44202" "44203" "44204"
## [3505] "44205" "44206" "44207" "44208" "44210" "44211" "44212" "44213"
## [3513] "44227" "44238" "44300" "44310" "44312" "44314" "44316" "44320"
## [3521] "44322" "44340" "44345" "44346" "44360" "44361" "44363" "44364"
## [3529] "44365" "44366" "44369" "44370" "44372" "44373" "44376" "44377"
## [3537] "44378" "44379" "44380" "44382" "44383" "44385" "44386" "44388"
## [3545] "44389" "44390" "44391" "44392" "44393" "44394" "44397" "44500"
## [3553] "44602" "44603" "44604" "44605" "44615" "44620" "44625" "44626"
## [3561] "44640" "44650" "44660" "44661" "44680" "44700" "44701" "44705"
## [3569] "44715" "44720" "44721" "44799" "44800" "44820" "44850" "44899"
## [3577] "44900" "44901" "44950" "44955" "44960" "44970" "44979" "45000"
## [3585] "45005" "45020" "45100" "45108" "45110" "45111" "45112" "45113"
## [3593] "45114" "45116" "45119" "45120" "45121" "45123" "45126" "45130"
## [3601] "45135" "45136" "45150" "45160" "45171" "45172" "45190" "45300"
## [3609] "45303" "45305" "45307" "45308" "45309" "45315" "45317" "45320"
## [3617] "45321" "45327" "45330" "45331" "45332" "45333" "45334" "45335"
## [3625] "45337" "45338" "45339" "45340" "45341" "45342" "45345" "45355"
## [3633] "45378" "45379" "45380" "45381" "45382" "45383" "45384" "45385"
## [3641] "45386" "45387" "45391" "45392" "45395" "45397" "45400" "45402"
## [3649] "45499" "45500" "45505" "45520" "45540" "45541" "45550" "45560"
## [3657] "45562" "45563" "45800" "45805" "45820" "45825" "45900" "45905"
## [3665] "45910" "45915" "45990" "45999" "46020" "46030" "46040" "46045"
## [3673] "46050" "46060" "46070" "46080" "46083" "46200" "46220" "46221"
## [3681] "46230" "46250" "46255" "46257" "46258" "46260" "46261" "46262"
## [3689] "46270" "46275" "46280" "46285" "46288" "46320" "46500" "46505"
## [3697] "46600" "46604" "46606" "46608" "46610" "46611" "46612" "46614"
## [3705] "46615" "46700" "46705" "46706" "46707" "46710" "46712" "46715"
## [3713] "46716" "46730" "46735" "46740" "46742" "46744" "46746" "46748"
## [3721] "46750" "46751" "46753" "46754" "46760" "46761" "46762" "46900"
## [3729] "46910" "46916" "46917" "46922" "46924" "46930" "46940" "46942"
## [3737] "46945" "46946" "46947" "46999" "47000" "47001" "47010" "47011"
## [3745] "47015" "47100" "47120" "47122" "47125" "47130" "47133" "47135"
## [3753] "47136" "47140" "47141" "47142" "47143" "47144" "47145" "47146"
## [3761] "47147" "47300" "47350" "47360" "47361" "47362" "47370" "47371"
## [3769] "47379" "47380" "47381" "47382" "47399" "47400" "47420" "47425"
## [3777] "47460" "47480" "47490" "47500" "47505" "47510" "47511" "47525"
## [3785] "47530" "47550" "47552" "47553" "47554" "47555" "47556" "47560"
## [3793] "47561" "47562" "47563" "47564" "47570" "47579" "47600" "47605"
## [3801] "47610" "47612" "47620" "47630" "47700" "47701" "47711" "47712"
## [3809] "47715" "47720" "47721" "47740" "47741" "47760" "47765" "47780"
## [3817] "47785" "47800" "47801" "47802" "47900" "47999" "48000" "48001"
## [3825] "48020" "48100" "48102" "48105" "48120" "48140" "48145" "48146"
## [3833] "48148" "48150" "48152" "48153" "48154" "48155" "48160" "48400"
## [3841] "48500" "48510" "48511" "48520" "48540" "48545" "48547" "48548"
## [3849] "48550" "48551" "48552" "48554" "48556" "48999" "49000" "49002"
## [3857] "49010" "49020" "49021" "49040" "49041" "49060" "49061" "49062"
## [3865] "49082" "49083" "49084" "49180" "49203" "49204" "49205" "49215"
## [3873] "49220" "49250" "49255" "49320" "49321" "49322" "49323" "49324"
## [3881] "49325" "49326" "49327" "49329" "49400" "49402" "49411" "49412"
## [3889] "49418" "49419" "49421" "49422" "49423" "49424" "49425" "49426"
## [3897] "49427" "49428" "49429" "49435" "49436" "49440" "49441" "49442"
## [3905] "49446" "49450" "49451" "49452" "49460" "49465" "49491" "49492"
## [3913] "49495" "49496" "49500" "49501" "49505" "49507" "49520" "49521"
## [3921] "49525" "49540" "49550" "49553" "49555" "49557" "49560" "49561"
## [3929] "49565" "49566" "49568" "49570" "49572" "49580" "49582" "49585"
## [3937] "49587" "49590" "49600" "49605" "49606" "49610" "49611" "49650"
## [3945] "49651" "49652" "49653" "49654" "49655" "49656" "49657" "49659"
## [3953] "49900" "49904" "49905" "49906" "49999" "50010" "50020" "50021"
## [3961] "50040" "50045" "50060" "50065" "50070" "50075" "50080" "50081"
## [3969] "50100" "50120" "50125" "50130" "50135" "50200" "50205" "50220"
## [3977] "50225" "50230" "50234" "50236" "50240" "50250" "50280" "50290"
## [3985] "50300" "50320" "50323" "50325" "50327" "50328" "50329" "50340"
## [3993] "50360" "50365" "50370" "50380" "50382" "50384" "50385" "50386"
## [4001] "50387" "50389" "50390" "50391" "50392" "50393" "50394" "50395"
## [4009] "50396" "50398" "50400" "50405" "50500" "50520" "50525" "50526"
## [4017] "50540" "50541" "50542" "50543" "50544" "50545" "50546" "50547"
## [4025] "50548" "50549" "50551" "50553" "50555" "50557" "50561" "50562"
## [4033] "50570" "50572" "50574" "50575" "50576" "50580" "50590" "50592"
## [4041] "50593" "50600" "50605" "50610" "50620" "50630" "50650" "50660"
## [4049] "50684" "50686" "50688" "50690" "50700" "50715" "50722" "50725"
## [4057] "50727" "50728" "50740" "50750" "50760" "50770" "50780" "50782"
## [4065] "50783" "50785" "50800" "50810" "50815" "50820" "50825" "50830"
## [4073] "50840" "50845" "50860" "50900" "50920" "50930" "50940" "50945"
## [4081] "50947" "50948" "50949" "50951" "50953" "50955" "50957" "50961"
## [4089] "50970" "50972" "50974" "50976" "50980" "51020" "51030" "51040"
## [4097] "51045" "51050" "51060" "51065" "51080" "51100" "51101" "51102"
## [4105] "51500" "51520" "51525" "51530" "51535" "51550" "51555" "51565"
## [4113] "51570" "51575" "51580" "51585" "51590" "51595" "51596" "51597"
## [4121] "51600" "51605" "51610" "51700" "51701" "51702" "51703" "51705"
## [4129] "51710" "51715" "51720" "51725" "51726" "51727" "51728" "51729"
## [4137] "51736" "51741" "51784" "51785" "51792" "51797" "51798" "51800"
## [4145] "51820" "51840" "51841" "51845" "51860" "51865" "51880" "51900"
## [4153] "51920" "51925" "51940" "51960" "51980" "51990" "51992" "51999"
## [4161] "52000" "52001" "52005" "52007" "52010" "52204" "52214" "52224"
## [4169] "52234" "52235" "52240" "52250" "52260" "52265" "52270" "52275"
## [4177] "52276" "52277" "52281" "52282" "52283" "52285" "52287" "52290"
## [4185] "52300" "52301" "52305" "52310" "52315" "52317" "52318" "52320"
## [4193] "52325" "52327" "52330" "52332" "52334" "52341" "52342" "52343"
## [4201] "52344" "52345" "52346" "52351" "52352" "52353" "52354" "52355"
## [4209] "52400" "52402" "52450" "52500" "52601" "52630" "52640" "52647"
## [4217] "52648" "52649" "52700" "53000" "53010" "53020" "53025" "53040"
## [4225] "53060" "53080" "53085" "53200" "53210" "53215" "53220" "53230"
## [4233] "53235" "53240" "53250" "53260" "53265" "53270" "53275" "53400"
## [4241] "53405" "53410" "53415" "53420" "53425" "53430" "53431" "53440"
## [4249] "53442" "53444" "53445" "53446" "53447" "53448" "53449" "53450"
## [4257] "53460" "53500" "53502" "53505" "53510" "53515" "53520" "53600"
## [4265] "53601" "53605" "53620" "53621" "53660" "53661" "53665" "53850"
## [4273] "53852" "53855" "53860" "53899" "54000" "54001" "54015" "54050"
## [4281] "54055" "54056" "54057" "54060" "54065" "54100" "54105" "54110"
## [4289] "54111" "54112" "54115" "54120" "54125" "54130" "54135" "54150"
## [4297] "54160" "54161" "54162" "54163" "54164" "54200" "54205" "54220"
## [4305] "54230" "54231" "54235" "54240" "54250" "54300" "54304" "54308"
## [4313] "54312" "54316" "54318" "54322" "54324" "54326" "54328" "54332"
## [4321] "54336" "54340" "54344" "54348" "54352" "54360" "54380" "54385"
## [4329] "54390" "54400" "54401" "54405" "54406" "54408" "54410" "54411"
## [4337] "54415" "54416" "54417" "54420" "54430" "54435" "54440" "54450"
## [4345] "54500" "54505" "54512" "54520" "54522" "54530" "54535" "54550"
## [4353] "54560" "54600" "54620" "54640" "54650" "54660" "54670" "54680"
## [4361] "54690" "54692" "54699" "54700" "54800" "54830" "54840" "54860"
## [4369] "54861" "54865" "54900" "54901" "55000" "55040" "55041" "55060"
## [4377] "55100" "55110" "55120" "55150" "55175" "55180" "55200" "55250"
## [4385] "55300" "55400" "55450" "55500" "55520" "55530" "55535" "55540"
## [4393] "55550" "55559" "55600" "55605" "55650" "55680" "55700" "55705"
## [4401] "55706" "55720" "55725" "55801" "55810" "55812" "55815" "55821"
## [4409] "55831" "55840" "55842" "55845" "55860" "55862" "55865" "55866"
## [4417] "55870" "55873" "55875" "55876" "55899" "55920" "55970" "55980"
## [4425] "56405" "56420" "56440" "56441" "56442" "56501" "56515" "56605"
## [4433] "56606" "56620" "56625" "56630" "56631" "56632" "56633" "56634"
## [4441] "56637" "56640" "56700" "56740" "56800" "56805" "56810" "56820"
## [4449] "56821" "57000" "57010" "57020" "57022" "57023" "57061" "57065"
## [4457] "57100" "57105" "57106" "57107" "57109" "57110" "57111" "57112"
## [4465] "57120" "57130" "57135" "57150" "57155" "57156" "57160" "57170"
## [4473] "57180" "57200" "57210" "57220" "57230" "57240" "57250" "57260"
## [4481] "57265" "57267" "57268" "57270" "57280" "57282" "57283" "57284"
## [4489] "57285" "57287" "57288" "57289" "57291" "57292" "57295" "57296"
## [4497] "57300" "57305" "57307" "57308" "57310" "57311" "57320" "57330"
## [4505] "57335" "57400" "57410" "57415" "57420" "57421" "57423" "57425"
## [4513] "57426" "57452" "57454" "57455" "57456" "57460" "57461" "57500"
## [4521] "57505" "57510" "57511" "57513" "57520" "57522" "57530" "57531"
## [4529] "57540" "57545" "57550" "57555" "57556" "57558" "57700" "57720"
## [4537] "57800" "58100" "58110" "58120" "58140" "58145" "58146" "58150"
## [4545] "58152" "58180" "58200" "58210" "58240" "58260" "58262" "58263"
## [4553] "58267" "58270" "58275" "58280" "58285" "58290" "58291" "58292"
## [4561] "58293" "58294" "58300" "58301" "58321" "58322" "58323" "58340"
## [4569] "58345" "58346" "58350" "58353" "58356" "58400" "58410" "58520"
## [4577] "58540" "58541" "58542" "58543" "58544" "58545" "58546" "58548"
## [4585] "58550" "58552" "58553" "58554" "58555" "58558" "58559" "58560"
## [4593] "58561" "58562" "58563" "58565" "58570" "58571" "58572" "58573"
## [4601] "58578" "58579" "58600" "58605" "58611" "58615" "58660" "58661"
## [4609] "58662" "58670" "58671" "58672" "58673" "58679" "58700" "58720"
## [4617] "58740" "58750" "58752" "58760" "58770" "58800" "58805" "58820"
## [4625] "58822" "58823" "58825" "58900" "58920" "58925" "58940" "58943"
## [4633] "58950" "58951" "58952" "58953" "58954" "58956" "58957" "58958"
## [4641] "58960" "58970" "58974" "58976" "58999" "59000" "59001" "59012"
## [4649] "59015" "59020" "59025" "59030" "59050" "59051" "59070" "59072"
## [4657] "59074" "59076" "59100" "59120" "59121" "59130" "59135" "59136"
## [4665] "59140" "59150" "59151" "59160" "59200" "59300" "59320" "59325"
## [4673] "59350" "59400" "59409" "59410" "59412" "59414" "59425" "59426"
## [4681] "59430" "59510" "59514" "59515" "59525" "59610" "59612" "59614"
## [4689] "59618" "59620" "59622" "59812" "59820" "59821" "59830" "59840"
## [4697] "59841" "59850" "59851" "59852" "59855" "59856" "59857" "59866"
## [4705] "59870" "59871" "59897" "59898" "59899" "60000" "60100" "60200"
## [4713] "60210" "60212" "60220" "60225" "60240" "60252" "60254" "60260"
## [4721] "60270" "60271" "60280" "60281" "60300" "60500" "60502" "60505"
## [4729] "60512" "60520" "60521" "60522" "60540" "60545" "60600" "60605"
## [4737] "60650" "60659" "60699" "61000" "61001" "61020" "61026" "61050"
## [4745] "61055" "61070" "61105" "61107" "61108" "61120" "61140" "61150"
## [4753] "61151" "61154" "61156" "61210" "61215" "61250" "61253" "61304"
## [4761] "61305" "61312" "61313" "61314" "61315" "61316" "61320" "61321"
## [4769] "61322" "61323" "61330" "61332" "61333" "61334" "61340" "61343"
## [4777] "61345" "61440" "61450" "61458" "61460" "61470" "61480" "61490"
## [4785] "61500" "61501" "61510" "61512" "61514" "61516" "61517" "61518"
## [4793] "61519" "61520" "61521" "61522" "61524" "61526" "61530" "61531"
## [4801] "61533" "61534" "61535" "61536" "61537" "61538" "61539" "61540"
## [4809] "61541" "61542" "61543" "61544" "61545" "61546" "61548" "61550"
## [4817] "61552" "61556" "61557" "61558" "61559" "61563" "61564" "61566"
## [4825] "61567" "61570" "61571" "61575" "61576" "61580" "61581" "61582"
## [4833] "61583" "61584" "61585" "61586" "61590" "61591" "61592" "61595"
## [4841] "61596" "61597" "61598" "61600" "61601" "61605" "61606" "61607"
## [4849] "61608" "61609" "61610" "61611" "61612" "61613" "61615" "61616"
## [4857] "61618" "61619" "61623" "61624" "61626" "61630" "61635" "61640"
## [4865] "61641" "61642" "61680" "61682" "61684" "61686" "61690" "61692"
## [4873] "61697" "61698" "61700" "61702" "61703" "61705" "61708" "61710"
## [4881] "61711" "61720" "61735" "61750" "61751" "61760" "61770" "61781"
## [4889] "61782" "61783" "61790" "61791" "61796" "61797" "61798" "61799"
## [4897] "61800" "61850" "61860" "61863" "61864" "61867" "61868" "61870"
## [4905] "61875" "61880" "61885" "61886" "61888" "62000" "62005" "62010"
## [4913] "62100" "62115" "62116" "62117" "62120" "62121" "62140" "62141"
## [4921] "62142" "62143" "62145" "62146" "62147" "62148" "62160" "62161"
## [4929] "62162" "62163" "62164" "62165" "62180" "62190" "62192" "62194"
## [4937] "62200" "62201" "62220" "62223" "62225" "62230" "62252" "62256"
## [4945] "62258" "62263" "62264" "62267" "62268" "62269" "62270" "62272"
## [4953] "62273" "62280" "62281" "62282" "62284" "62287" "62290" "62291"
## [4961] "62292" "62294" "62310" "62311" "62318" "62319" "62350" "62351"
## [4969] "62355" "62360" "62361" "62362" "62365" "62367" "62368" "62369"
## [4977] "62370" "63001" "63003" "63005" "63011" "63012" "63015" "63016"
## [4985] "63017" "63020" "63030" "63035" "63040" "63042" "63043" "63044"
## [4993] "63045" "63046" "63047" "63048" "63050" "63051" "63055" "63056"
## [5001] "63057" "63064" "63066" "63075" "63076" "63077" "63078" "63081"
## [5009] "63082" "63085" "63086" "63087" "63088" "63090" "63091" "63101"
## [5017] "63102" "63103" "63170" "63172" "63173" "63180" "63182" "63185"
## [5025] "63190" "63191" "63194" "63195" "63196" "63197" "63198" "63199"
## [5033] "63200" "63250" "63251" "63252" "63265" "63266" "63267" "63268"
## [5041] "63270" "63271" "63272" "63273" "63275" "63276" "63277" "63278"
## [5049] "63280" "63281" "63282" "63283" "63285" "63286" "63287" "63290"
## [5057] "63295" "63300" "63301" "63302" "63303" "63304" "63305" "63306"
## [5065] "63307" "63308" "63600" "63610" "63615" "63620" "63621" "63650"
## [5073] "63655" "63661" "63662" "63663" "63664" "63685" "63688" "63700"
## [5081] "63702" "63704" "63706" "63707" "63709" "63710" "63740" "63741"
## [5089] "63744" "63746" "64400" "64402" "64405" "64408" "64410" "64412"
## [5097] "64413" "64415" "64416" "64417" "64418" "64420" "64421" "64425"
## [5105] "64430" "64435" "64445" "64446" "64447" "64448" "64449" "64450"
## [5113] "64455" "64479" "64480" "64483" "64484" "64490" "64491" "64492"
## [5121] "64493" "64494" "64495" "64505" "64508" "64510" "64517" "64520"
## [5129] "64530" "64550" "64553" "64555" "64561" "64565" "64566" "64568"
## [5137] "64569" "64570" "64575" "64580" "64581" "64585" "64590" "64595"
## [5145] "64600" "64605" "64610" "64611" "64612" "64613" "64614" "64615"
## [5153] "64620" "64630" "64632" "64633" "64634" "64635" "64636" "64640"
## [5161] "64650" "64653" "64680" "64681" "64702" "64704" "64708" "64712"
## [5169] "64713" "64714" "64716" "64718" "64719" "64721" "64722" "64726"
## [5177] "64727" "64732" "64734" "64736" "64738" "64740" "64742" "64744"
## [5185] "64746" "64752" "64755" "64760" "64761" "64763" "64766" "64771"
## [5193] "64772" "64774" "64776" "64778" "64782" "64783" "64784" "64786"
## [5201] "64787" "64788" "64790" "64792" "64795" "64802" "64804" "64809"
## [5209] "64818" "64820" "64821" "64822" "64823" "64831" "64832" "64834"
## [5217] "64835" "64836" "64837" "64840" "64856" "64857" "64858" "64859"
## [5225] "64861" "64862" "64864" "64865" "64866" "64868" "64870" "64872"
## [5233] "64874" "64876" "64885" "64886" "64890" "64891" "64892" "64893"
## [5241] "64895" "64896" "64897" "64898" "64901" "64902" "64905" "64907"
## [5249] "64910" "64911" "64999" "65091" "65093" "65101" "65103" "65105"
## [5257] "65110" "65112" "65114" "65125" "65130" "65135" "65140" "65150"
## [5265] "65155" "65175" "65205" "65210" "65220" "65222" "65235" "65260"
## [5273] "65265" "65270" "65272" "65273" "65275" "65280" "65285" "65286"
## [5281] "65290" "65400" "65410" "65420" "65426" "65430" "65435" "65436"
## [5289] "65450" "65600" "65710" "65730" "65750" "65755" "65756" "65757"
## [5297] "65760" "65765" "65767" "65770" "65771" "65772" "65775" "65778"
## [5305] "65779" "65780" "65781" "65782" "65800" "65805" "65810" "65815"
## [5313] "65820" "65850" "65855" "65860" "65865" "65870" "65875" "65880"
## [5321] "65900" "65920" "65930" "66020" "66030" "66130" "66150" "66155"
## [5329] "66160" "66165" "66170" "66172" "66174" "66175" "66180" "66185"
## [5337] "66220" "66225" "66250" "66500" "66505" "66600" "66605" "66625"
## [5345] "66630" "66635" "66680" "66682" "66700" "66710" "66711" "66720"
## [5353] "66740" "66761" "66762" "66770" "66820" "66821" "66825" "66830"
## [5361] "66840" "66850" "66852" "66920" "66930" "66940" "66982" "66983"
## [5369] "66984" "66985" "66986" "66990" "66999" "67005" "67010" "67015"
## [5377] "67025" "67027" "67028" "67030" "67031" "67036" "67039" "67040"
## [5385] "67041" "67042" "67043" "67101" "67105" "67107" "67108" "67110"
## [5393] "67112" "67113" "67115" "67120" "67121" "67141" "67145" "67208"
## [5401] "67210" "67218" "67220" "67221" "67225" "67227" "67228" "67229"
## [5409] "67250" "67255" "67299" "67311" "67312" "67314" "67316" "67318"
## [5417] "67320" "67331" "67332" "67334" "67335" "67340" "67343" "67345"
## [5425] "67346" "67399" "67400" "67405" "67412" "67413" "67414" "67415"
## [5433] "67420" "67430" "67440" "67445" "67450" "67500" "67505" "67515"
## [5441] "67550" "67560" "67570" "67599" "67700" "67710" "67715" "67800"
## [5449] "67801" "67805" "67808" "67810" "67820" "67825" "67830" "67835"
## [5457] "67840" "67850" "67875" "67880" "67882" "67900" "67901" "67902"
## [5465] "67903" "67904" "67906" "67908" "67909" "67911" "67912" "67914"
## [5473] "67915" "67916" "67917" "67921" "67922" "67923" "67924" "67930"
## [5481] "67935" "67938" "67950" "67961" "67966" "67971" "67973" "67974"
## [5489] "67975" "67999" "68020" "68040" "68100" "68110" "68115" "68130"
## [5497] "68135" "68200" "68320" "68325" "68326" "68328" "68330" "68335"
## [5505] "68340" "68360" "68362" "68371" "68399" "68400" "68420" "68440"
## [5513] "68500" "68505" "68510" "68520" "68525" "68530" "68540" "68550"
## [5521] "68700" "68705" "68720" "68745" "68750" "68760" "68761" "68770"
## [5529] "68801" "68810" "68811" "68815" "68816" "68840" "68850" "68899"
## [5537] "69000" "69005" "69020" "69090" "69100" "69105" "69110" "69120"
## [5545] "69140" "69145" "69150" "69155" "69200" "69205" "69210" "69220"
## [5553] "69222" "69300" "69310" "69320" "69399" "69400" "69401" "69405"
## [5561] "69420" "69421" "69424" "69433" "69436" "69440" "69450" "69501"
## [5569] "69502" "69505" "69511" "69530" "69535" "69540" "69550" "69552"
## [5577] "69554" "69601" "69602" "69603" "69604" "69605" "69610" "69620"
## [5585] "69631" "69632" "69633" "69635" "69636" "69637" "69641" "69642"
## [5593] "69643" "69644" "69645" "69646" "69650" "69660" "69661" "69662"
## [5601] "69666" "69667" "69670" "69676" "69700" "69710" "69711" "69714"
## [5609] "69715" "69717" "69718" "69720" "69725" "69740" "69745" "69799"
## [5617] "69801" "69805" "69806" "69820" "69840" "69905" "69910" "69915"
## [5625] "69930" "69949" "69950" "69955" "69960" "69970" "69979"
## 
## $icd9cm
## character(0)
## 
## $icd9pcs
## character(0)
## 
## $drg
## character(0)
## 
## $ubRev
## character(0)
## 
## $pos
## character(0)
## 
## $typeOfBill
## character(0)
lCodesEDPOS <- makeList("ED POS")
## $valueSetName
## [1] "ED POS"
## 
## $summary
##      
##       ED POS
##   pos      1
## 
## $cpt
## character(0)
## 
## $icd9cm
## character(0)
## 
## $icd9pcs
## character(0)
## 
## $drg
## character(0)
## 
## $ubRev
## character(0)
## 
## $pos
## [1] "23"
## 
## $typeOfBill
## character(0)
lCodesOutpatient <- makeList("Outpatient")
## $valueSetName
## [1] "Outpatient"
## 
## $summary
##        
##         Outpatient
##   cpt           51
##   ubRev         19
## 
## $cpt
##  [1] "99201" "99202" "99203" "99204" "99205" "99211" "99212" "99213"
##  [9] "99214" "99215" "99241" "99242" "99243" "99244" "99245" "99341"
## [17] "99342" "99343" "99344" "99345" "99347" "99348" "99349" "99350"
## [25] "99381" "99382" "99383" "99384" "99385" "99386" "99387" "99391"
## [33] "99392" "99393" "99394" "99395" "99396" "99397" "99401" "99402"
## [41] "99403" "99404" "99411" "99412" "99420" "99429" "99455" "99456"
## [49] "G0402" "G0438" "G0439"
## 
## $icd9cm
## character(0)
## 
## $icd9pcs
## character(0)
## 
## $drg
## character(0)
## 
## $ubRev
##  [1] "0510" "0511" "0512" "0513" "0514" "0515" "0516" "0517" "0519" "0520"
## [11] "0521" "0522" "0523" "0526" "0527" "0528" "0529" "0982" "0983"
## 
## $pos
## character(0)
## 
## $typeOfBill
## character(0)
lCodesAmbulatoryOutpatient <- makeList("Ambulatory Outpatient Visits")
## $valueSetName
## [1] "Ambulatory Outpatient Visits"
## 
## $summary
##        
##         Ambulatory Outpatient Visits
##   cpt                             70
##   ubRev                           21
## 
## $cpt
##  [1] "92002" "92004" "92012" "92014" "99201" "99202" "99203" "99204"
##  [9] "99205" "99211" "99212" "99213" "99214" "99215" "99241" "99242"
## [17] "99243" "99244" "99245" "99304" "99305" "99306" "99307" "99308"
## [25] "99309" "99310" "99315" "99316" "99318" "99324" "99325" "99326"
## [33] "99327" "99328" "99334" "99335" "99336" "99337" "99341" "99342"
## [41] "99343" "99344" "99345" "99347" "99348" "99349" "99350" "99381"
## [49] "99382" "99383" "99384" "99385" "99386" "99387" "99391" "99392"
## [57] "99393" "99394" "99395" "99396" "99397" "99401" "99402" "99403"
## [65] "99404" "99411" "99412" "99420" "99429" "99461"
## 
## $icd9cm
## character(0)
## 
## $icd9pcs
## character(0)
## 
## $drg
## character(0)
## 
## $ubRev
##  [1] "0510" "0511" "0512" "0513" "0514" "0515" "0516" "0517" "0519" "0520"
## [11] "0521" "0522" "0523" "0524" "0525" "0526" "0527" "0528" "0529" "0982"
## [21] "0983"
## 
## $pos
## character(0)
## 
## $typeOfBill
## character(0)
lCodesDetox <- makeList("Detoxification")
## $valueSetName
## [1] "Detoxification"
## 
## $summary
##          
##           Detoxification
##   cpt                  7
##   icd9pcs              3
##   ubRev                5
## 
## $cpt
## [1] "H0008" "H0009" "H0010" "H0011" "H0012" "H0013" "H0014"
## 
## $icd9cm
## character(0)
## 
## $icd9pcs
## [1] "9462" "9465" "9468"
## 
## $drg
## character(0)
## 
## $ubRev
## [1] "0116" "0126" "0136" "0146" "0156"
## 
## $pos
## character(0)
## 
## $typeOfBill
## character(0)
lCodesPregnancy <- makeList("Pregnancy")
## $valueSetName
## [1] "Pregnancy"
## 
## $summary
##         
##          Pregnancy
##   icd9cm      1491
## 
## $cpt
## character(0)
## 
## $icd9cm
##    [1] "630"   "6310"  "631"   "6318"  "632"   "6330"  "63300" "633"  
##    [9] "63301" "6331"  "63310" "63311" "6332"  "63320" "63321" "6338" 
##   [17] "63380" "63381" "6339"  "63390" "63391" "6340"  "634"   "63400"
##   [25] "63401" "63402" "6341"  "63410" "63411" "63412" "6342"  "63420"
##   [33] "63421" "63422" "6343"  "63430" "63431" "63432" "6344"  "63440"
##   [41] "63441" "63442" "6345"  "63450" "63451" "63452" "6346"  "63460"
##   [49] "63461" "63462" "63470" "6347"  "63471" "63472" "63480" "6348" 
##   [57] "63481" "63482" "63490" "6349"  "63491" "63492" "6350"  "635"  
##   [65] "63500" "63501" "63502" "6351"  "63510" "63511" "63512" "6352" 
##   [73] "63520" "63521" "63522" "6353"  "63530" "63531" "63532" "6354" 
##   [81] "63540" "63541" "63542" "6355"  "63550" "63551" "63552" "6356" 
##   [89] "63560" "63561" "63562" "63570" "6357"  "63571" "63572" "63580"
##   [97] "6358"  "63581" "63582" "63590" "6359"  "63591" "63592" "6360" 
##  [105] "636"   "63600" "63601" "63602" "6361"  "63610" "63611" "63612"
##  [113] "6362"  "63620" "63621" "63622" "6363"  "63630" "63631" "63632"
##  [121] "6364"  "63640" "63641" "63642" "6365"  "63650" "63651" "63652"
##  [129] "6366"  "63660" "63661" "63662" "63670" "6367"  "63671" "63672"
##  [137] "63680" "6368"  "63681" "63682" "63690" "6369"  "63691" "63692"
##  [145] "6370"  "637"   "63700" "63701" "63702" "6371"  "63710" "63711"
##  [153] "63712" "6372"  "63720" "63721" "63722" "6373"  "63730" "63731"
##  [161] "63732" "6374"  "63740" "63741" "63742" "6375"  "63750" "63751"
##  [169] "63752" "6376"  "63760" "63761" "63762" "63770" "6377"  "63771"
##  [177] "63772" "63780" "6378"  "63781" "63782" "63790" "6379"  "63791"
##  [185] "63792" "6380"  "638"   "6381"  "6382"  "6383"  "6384"  "6385" 
##  [193] "6386"  "6387"  "6388"  "6389"  "639"   "6390"  "6391"  "6392" 
##  [201] "6393"  "6394"  "6395"  "6396"  "6398"  "6399"  "640"   "6400" 
##  [209] "64000" "64001" "64003" "6408"  "64080" "64081" "64083" "6409" 
##  [217] "64090" "64091" "64093" "641"   "6410"  "64100" "64101" "64103"
##  [225] "6411"  "64110" "64111" "64113" "6412"  "64120" "64121" "64123"
##  [233] "6413"  "64130" "64131" "64133" "6418"  "64180" "64181" "64183"
##  [241] "6419"  "64190" "64191" "64193" "6420"  "64200" "642"   "64201"
##  [249] "64202" "64203" "64204" "6421"  "64210" "64211" "64212" "64213"
##  [257] "64214" "6422"  "64220" "64221" "64222" "64223" "64224" "6423" 
##  [265] "64230" "64231" "64232" "64233" "64234" "6424"  "64240" "64241"
##  [273] "64242" "64243" "64244" "6425"  "64250" "64251" "64252" "64253"
##  [281] "64254" "6426"  "64260" "64261" "64262" "64263" "64264" "6427" 
##  [289] "64270" "64271" "64272" "64273" "64274" "6429"  "64290" "64291"
##  [297] "64292" "64293" "64294" "643"   "6430"  "64300" "64301" "64303"
##  [305] "6431"  "64310" "64311" "64313" "6432"  "64320" "64321" "64323"
##  [313] "6438"  "64380" "64381" "64383" "6439"  "64390" "64391" "64393"
##  [321] "644"   "6440"  "64400" "64403" "6441"  "64410" "64413" "6442" 
##  [329] "64420" "64421" "645"   "6451"  "64510" "64511" "64513" "6452" 
##  [337] "64520" "64521" "64523" "646"   "6460"  "64600" "64601" "64603"
##  [345] "6461"  "64610" "64611" "64612" "64613" "64614" "6462"  "64620"
##  [353] "64621" "64622" "64623" "64624" "6463"  "64630" "64631" "64633"
##  [361] "6464"  "64640" "64641" "64642" "64643" "64644" "6465"  "64650"
##  [369] "64651" "64652" "64653" "64654" "6466"  "64660" "64661" "64662"
##  [377] "64663" "64664" "6467"  "64670" "64671" "64673" "6468"  "64680"
##  [385] "64681" "64682" "64683" "64684" "6469"  "64690" "64691" "64693"
##  [393] "647"   "6470"  "64700" "64701" "64702" "64703" "64704" "6471" 
##  [401] "64710" "64711" "64712" "64713" "64714" "6472"  "64720" "64721"
##  [409] "64722" "64723" "64724" "6473"  "64730" "64731" "64732" "64733"
##  [417] "64734" "6474"  "64740" "64741" "64742" "64743" "64744" "6475" 
##  [425] "64750" "64751" "64752" "64753" "64754" "6476"  "64760" "64761"
##  [433] "64762" "64763" "64764" "6478"  "64780" "64781" "64782" "64783"
##  [441] "64784" "6479"  "64790" "64791" "64792" "64793" "64794" "6480" 
##  [449] "64800" "648"   "64801" "64802" "64803" "64804" "6481"  "64810"
##  [457] "64811" "64812" "64813" "64814" "6482"  "64820" "64821" "64822"
##  [465] "64823" "64824" "6483"  "64830" "64831" "64832" "64833" "64834"
##  [473] "6484"  "64840" "64841" "64842" "64843" "64844" "6485"  "64850"
##  [481] "64851" "64852" "64853" "64854" "6486"  "64860" "64861" "64862"
##  [489] "64863" "64864" "6487"  "64870" "64871" "64872" "64873" "64874"
##  [497] "6488"  "64880" "64881" "64882" "64883" "64884" "6489"  "64890"
##  [505] "64891" "64892" "64893" "64894" "649"   "6490"  "64900" "64901"
##  [513] "64902" "64903" "64904" "6491"  "64910" "64911" "64912" "64913"
##  [521] "64914" "6492"  "64920" "64921" "64922" "64923" "64924" "6493" 
##  [529] "64930" "64931" "64932" "64933" "64934" "6494"  "64940" "64941"
##  [537] "64942" "64943" "64944" "6495"  "64950" "64951" "64953" "6496" 
##  [545] "64960" "64961" "64962" "64963" "64964" "6497"  "64970" "64971"
##  [553] "64973" "6498"  "64981" "64982" "650"   "651"   "6510"  "65100"
##  [561] "65101" "65103" "6511"  "65110" "65111" "65113" "6512"  "65120"
##  [569] "65121" "65123" "6513"  "65130" "65131" "65133" "6514"  "65140"
##  [577] "65141" "65143" "6515"  "65150" "65151" "65153" "6516"  "65160"
##  [585] "65161" "65163" "6517"  "65170" "65171" "65173" "6518"  "65180"
##  [593] "65181" "65183" "6519"  "65190" "65191" "65193" "652"   "6520" 
##  [601] "65200" "65201" "65203" "6521"  "65210" "65211" "65213" "6522" 
##  [609] "65220" "65221" "65223" "6523"  "65230" "65231" "65233" "6524" 
##  [617] "65240" "65241" "65243" "6525"  "65250" "65251" "65253" "6526" 
##  [625] "65260" "65261" "65263" "6527"  "65270" "65271" "65273" "6528" 
##  [633] "65280" "65281" "65283" "6529"  "65290" "65291" "65293" "653"  
##  [641] "6530"  "65300" "65301" "65303" "6531"  "65310" "65311" "65313"
##  [649] "6532"  "65320" "65321" "65323" "6533"  "65330" "65331" "65333"
##  [657] "6534"  "65340" "65341" "65343" "6535"  "65350" "65351" "65353"
##  [665] "6536"  "65360" "65361" "65363" "6537"  "65370" "65371" "65373"
##  [673] "6538"  "65380" "65381" "65383" "6539"  "65390" "65391" "65393"
##  [681] "654"   "6540"  "65400" "65401" "65402" "65403" "65404" "6541" 
##  [689] "65410" "65411" "65412" "65413" "65414" "6542"  "65420" "65421"
##  [697] "65423" "6543"  "65430" "65431" "65432" "65433" "65434" "6544" 
##  [705] "65440" "65441" "65442" "65443" "65444" "6545"  "65450" "65451"
##  [713] "65452" "65453" "65454" "6546"  "65460" "65461" "65462" "65463"
##  [721] "65464" "6547"  "65470" "65471" "65472" "65473" "65474" "6548" 
##  [729] "65480" "65481" "65482" "65483" "65484" "6549"  "65490" "65491"
##  [737] "65492" "65493" "65494" "6550"  "65500" "655"   "65501" "65503"
##  [745] "6551"  "65510" "65511" "65513" "6552"  "65520" "65521" "65523"
##  [753] "6553"  "65530" "65531" "65533" "6554"  "65540" "65541" "65543"
##  [761] "6555"  "65550" "65551" "65553" "6556"  "65560" "65561" "65563"
##  [769] "6557"  "65570" "65571" "65573" "6558"  "65580" "65581" "65583"
##  [777] "6559"  "65590" "65591" "65593" "6560"  "65600" "656"   "65601"
##  [785] "65603" "6561"  "65610" "65611" "65613" "6562"  "65620" "65621"
##  [793] "65623" "6563"  "65630" "65631" "65633" "6564"  "65640" "65641"
##  [801] "65643" "6565"  "65650" "65651" "65653" "6566"  "65660" "65661"
##  [809] "65663" "6567"  "65670" "65671" "65673" "6568"  "65680" "65681"
##  [817] "65683" "6569"  "65690" "65691" "65693" "657"   "65700" "6570" 
##  [825] "65701" "65703" "6580"  "65800" "658"   "65801" "65803" "6581" 
##  [833] "65810" "65811" "65813" "6582"  "65820" "65821" "65823" "6583" 
##  [841] "65830" "65831" "65833" "6584"  "65840" "65841" "65843" "6588" 
##  [849] "65880" "65881" "65883" "6589"  "65890" "65891" "65893" "6590" 
##  [857] "65900" "659"   "65901" "65903" "6591"  "65910" "65911" "65913"
##  [865] "6592"  "65920" "65921" "65923" "6593"  "65930" "65931" "65933"
##  [873] "6594"  "65940" "65941" "65943" "6595"  "65950" "65951" "65953"
##  [881] "6596"  "65960" "65961" "65963" "6597"  "65970" "65971" "65973"
##  [889] "6598"  "65980" "65981" "65983" "6599"  "65990" "65991" "65993"
##  [897] "660"   "6600"  "66000" "66001" "66003" "6601"  "66010" "66011"
##  [905] "66013" "6602"  "66020" "66021" "66023" "6603"  "66030" "66031"
##  [913] "66033" "6604"  "66040" "66041" "66043" "6605"  "66050" "66051"
##  [921] "66053" "6606"  "66060" "66061" "66063" "6607"  "66070" "66071"
##  [929] "66073" "6608"  "66080" "66081" "66083" "6609"  "66090" "66091"
##  [937] "66093" "661"   "6610"  "66100" "66101" "66103" "6611"  "66110"
##  [945] "66111" "66113" "6612"  "66120" "66121" "66123" "6613"  "66130"
##  [953] "66131" "66133" "6614"  "66140" "66141" "66143" "6619"  "66190"
##  [961] "66191" "66193" "662"   "6620"  "66200" "66201" "66203" "6621" 
##  [969] "66210" "66211" "66213" "6622"  "66220" "66221" "66223" "6623" 
##  [977] "66230" "66231" "66233" "6630"  "66300" "663"   "66301" "66303"
##  [985] "66310" "6631"  "66311" "66313" "6632"  "66320" "66321" "66323"
##  [993] "6633"  "66330" "66331" "66333" "6634"  "66340" "66341" "66343"
## [1001] "6635"  "66350" "66351" "66353" "6636"  "66360" "66361" "66363"
## [1009] "6638"  "66380" "66381" "66383" "6639"  "66390" "66391" "66393"
## [1017] "6640"  "66400" "664"   "66401" "66404" "6641"  "66410" "66411"
## [1025] "66414" "6642"  "66420" "66421" "66424" "6643"  "66430" "66431"
## [1033] "66434" "6644"  "66440" "66441" "66444" "6645"  "66450" "66451"
## [1041] "66454" "6646"  "66460" "66461" "66464" "6648"  "66480" "66481"
## [1049] "66484" "6649"  "66490" "66491" "66494" "665"   "6650"  "66500"
## [1057] "66501" "66503" "6651"  "66510" "66511" "6652"  "66520" "66522"
## [1065] "66524" "6653"  "66530" "66531" "66534" "6654"  "66540" "66541"
## [1073] "66544" "6655"  "66550" "66551" "66554" "6656"  "66560" "66561"
## [1081] "66564" "6657"  "66570" "66571" "66572" "66574" "6658"  "66580"
## [1089] "66581" "66582" "66583" "66584" "6659"  "66590" "66591" "66592"
## [1097] "66593" "66594" "666"   "6660"  "66600" "66602" "66604" "6661" 
## [1105] "66610" "66612" "66614" "6662"  "66620" "66622" "66624" "6663" 
## [1113] "66630" "66632" "66634" "6670"  "667"   "66700" "66702" "66704"
## [1121] "6671"  "66710" "66712" "66714" "668"   "6680"  "66800" "66801"
## [1129] "66802" "66803" "66804" "6681"  "66810" "66811" "66812" "66813"
## [1137] "66814" "6682"  "66820" "66821" "66822" "66823" "66824" "6688" 
## [1145] "66880" "66881" "66882" "66883" "66884" "6689"  "66890" "66891"
## [1153] "66892" "66893" "66894" "6690"  "66900" "669"   "66901" "66902"
## [1161] "66903" "66904" "6691"  "66910" "66911" "66912" "66913" "66914"
## [1169] "6692"  "66920" "66921" "66922" "66923" "66924" "6693"  "66930"
## [1177] "66932" "66934" "6694"  "66940" "66941" "66942" "66943" "66944"
## [1185] "6695"  "66950" "66951" "6696"  "66960" "66961" "6697"  "66970"
## [1193] "66971" "6698"  "66980" "66981" "66982" "66983" "66984" "6699" 
## [1201] "66990" "66991" "66992" "66993" "66994" "670"   "6700"  "67000"
## [1209] "67002" "67004" "6701"  "67010" "67012" "67014" "6702"  "67020"
## [1217] "67022" "67024" "6703"  "67030" "67032" "67034" "6708"  "67080"
## [1225] "67082" "67084" "6710"  "67100" "671"   "67101" "67102" "67103"
## [1233] "67104" "6711"  "67110" "67111" "67112" "67113" "67114" "6712" 
## [1241] "67120" "67121" "67122" "67123" "67124" "6713"  "67130" "67131"
## [1249] "67133" "6714"  "67140" "67142" "67144" "6715"  "67150" "67151"
## [1257] "67152" "67153" "67154" "6718"  "67180" "67181" "67182" "67183"
## [1265] "67184" "6719"  "67190" "67191" "67192" "67193" "67194" "672"  
## [1273] "67200" "6720"  "67202" "67204" "6730"  "67300" "673"   "67301"
## [1281] "67302" "67303" "67304" "6731"  "67310" "67311" "67312" "67313"
## [1289] "67314" "6732"  "67320" "67321" "67322" "67323" "67324" "6733" 
## [1297] "67330" "67331" "67332" "67333" "67334" "67380" "6738"  "67381"
## [1305] "67382" "67383" "67384" "6740"  "67400" "674"   "67401" "67402"
## [1313] "67403" "67404" "6741"  "67410" "67412" "67414" "6742"  "67420"
## [1321] "67422" "67424" "6743"  "67430" "67432" "67434" "6744"  "67440"
## [1329] "67442" "67444" "6745"  "67450" "67451" "67452" "67453" "67454"
## [1337] "6748"  "67480" "67482" "67484" "6749"  "67490" "67492" "67494"
## [1345] "6750"  "67500" "675"   "67501" "67502" "67503" "67504" "6751" 
## [1353] "67510" "67511" "67512" "67513" "67514" "6752"  "67520" "67521"
## [1361] "67522" "67523" "67524" "6758"  "67580" "67581" "67582" "67583"
## [1369] "67584" "6759"  "67590" "67591" "67592" "67593" "67594" "676"  
## [1377] "6760"  "67600" "67601" "67602" "67603" "67604" "6761"  "67610"
## [1385] "67611" "67612" "67613" "67614" "6762"  "67620" "67621" "67622"
## [1393] "67623" "67624" "6763"  "67630" "67631" "67632" "67633" "67634"
## [1401] "6764"  "67640" "67641" "67642" "67643" "67644" "6765"  "67650"
## [1409] "67651" "67652" "67653" "67654" "6766"  "67660" "67661" "67662"
## [1417] "67663" "67664" "6768"  "67680" "67681" "67682" "67683" "67684"
## [1425] "6769"  "67690" "67691" "67692" "67693" "67694" "677"   "6780" 
## [1433] "67800" "678"   "67801" "67803" "6781"  "67810" "67811" "67813"
## [1441] "679"   "6790"  "67900" "67901" "67902" "67903" "67904" "6791" 
## [1449] "67910" "67911" "67912" "67913" "67914" "V22"   "V220"  "V221" 
## [1457] "V222"  "V23"   "V230"  "V231"  "V232"  "V233"  "V234"  "V2341"
## [1465] "V2342" "V2349" "V235"  "V237"  "V238"  "V2381" "V2382" "V2383"
## [1473] "V2384" "V2385" "V2386" "V2387" "V2389" "V239"  "V28"   "V280" 
## [1481] "V281"  "V282"  "V283"  "V284"  "V285"  "V286"  "V288"  "V2881"
## [1489] "V2882" "V2889" "V289" 
## 
## $icd9pcs
## character(0)
## 
## $drg
## character(0)
## 
## $ubRev
## character(0)
## 
## $pos
## character(0)
## 
## $typeOfBill
## character(0)

Create expanded lookups based on HEDIS value sets. These require a bit more finesse, so makeList won’t be much help. Remove . from ICD-9 codes.

v <- c("Value.Set.Name", "Code.System", "Code", "Definition")
df <- dfHedisValueSets[grep("^Ambulatory|^Outpatient", dfHedisValueSets[, "Value.Set.Name"]), c(v, "codeSysVar")]
t <- table(droplevels(df$codeSysVar), df$Value.Set.Name)
lCodesOutpatientExpanded <- list(name = "Outpatient, expanded",
                                 summary = t,
                                 cpt = as.character(df[df$codeSysVar == "cpt", "Code"]),
                                 icd9cm = gsub("\\.", "", df[df$codeSysVar == "icd9cm", "Code"]),
                                 ubRev = unique(df[df$codeSysVar == "ubRev", "Code"]))
lCodesOutpatientExpanded
## $name
## [1] "Outpatient, expanded"
## 
## $summary
##         
##          Ambulatory Outpatient Visits Ambulatory Visits Outpatient
##   cpt                              70                49         51
##   icd9cm                            0                 7          0
##   ubRev                            21                19         19
##         
##          Outpatient CPT
##   cpt                48
##   icd9cm              0
##   ubRev               0
## 
## $cpt
##   [1] "92002" "92004" "92012" "92014" "99201" "99202" "99203" "99204"
##   [9] "99205" "99211" "99212" "99213" "99214" "99215" "99241" "99242"
##  [17] "99243" "99244" "99245" "99304" "99305" "99306" "99307" "99308"
##  [25] "99309" "99310" "99315" "99316" "99318" "99324" "99325" "99326"
##  [33] "99327" "99328" "99334" "99335" "99336" "99337" "99341" "99342"
##  [41] "99343" "99344" "99345" "99347" "99348" "99349" "99350" "99381"
##  [49] "99382" "99383" "99384" "99385" "99386" "99387" "99391" "99392"
##  [57] "99393" "99394" "99395" "99396" "99397" "99401" "99402" "99403"
##  [65] "99404" "99411" "99412" "99420" "99429" "99461" "99201" "99202"
##  [73] "99203" "99204" "99205" "99211" "99212" "99213" "99214" "99215"
##  [81] "99241" "99242" "99243" "99244" "99245" "99341" "99342" "99343"
##  [89] "99344" "99345" "99347" "99348" "99349" "99350" "99381" "99382"
##  [97] "99383" "99384" "99385" "99386" "99387" "99391" "99392" "99393"
## [105] "99394" "99395" "99396" "99397" "99401" "99402" "99403" "99404"
## [113] "99411" "99412" "99420" "99429" "G0402" "G0438" "G0439" "99201"
## [121] "99202" "99203" "99204" "99205" "99211" "99212" "99213" "99214"
## [129] "99215" "99241" "99242" "99243" "99244" "99245" "99341" "99342"
## [137] "99343" "99344" "99345" "99347" "99348" "99349" "99350" "99381"
## [145] "99382" "99383" "99384" "99385" "99386" "99387" "99391" "99392"
## [153] "99393" "99394" "99395" "99396" "99397" "99401" "99402" "99403"
## [161] "99404" "99411" "99412" "99420" "99429" "99455" "99456" "G0402"
## [169] "G0438" "G0439" "99201" "99202" "99203" "99204" "99205" "99211"
## [177] "99212" "99213" "99214" "99215" "99241" "99242" "99243" "99244"
## [185] "99245" "99341" "99342" "99343" "99344" "99345" "99347" "99348"
## [193] "99349" "99350" "99381" "99382" "99383" "99384" "99385" "99386"
## [201] "99387" "99391" "99392" "99393" "99394" "99395" "99396" "99397"
## [209] "99401" "99402" "99403" "99404" "99411" "99412" "99420" "99429"
## [217] "99455" "99456"
## 
## $icd9cm
## [1] "V202" "V700" "V703" "V705" "V706" "V708" "V709"
## 
## $ubRev
##  [1] "0510" "0511" "0512" "0513" "0514" "0515" "0516" "0517" "0519" "0520"
## [11] "0521" "0522" "0523" "0524" "0525" "0526" "0527" "0528" "0529" "0982"
## [21] "0983"
df <- dfHedisValueSets[grep("^ED", dfHedisValueSets[, "Value.Set.Name"]), c(v, "codeSysVar")]
t <- table(droplevels(df$codeSysVar), df$Value.Set.Name)
rm(v, df, t)

Create primary care visit lookup.

Draft proposed algorithm based on (Chang et al. 2011)

  • Evaluation and Management –Office or Other Outpatient Services
    • New patient: 99201–99205
    • Established patient: 99211–99215
  • Consultations –Office or Other Outpatient Consultations
    • New or established patient: 99241–99245
  • Preventive Medicine Services
    • New patient: 99381–99387
    • Established patient: 99391–99397
  • Counseling Risk Factor Reduction and Behavior Change Intervention
    • New or established patient preventive medicine, individual counseling: 99401–99404
    • New or established patient preventive medicine, group counseling: 99411–99412
  • Other Preventive Medicine Services
    • Administration and interpretation or unlisted preventive: 99420-99429
regexPCP <- "(992[014][1-5])|(993[89][1-7])|(9940[1-4])|(9941[12])|(9942[0-9])"

4.5 Mental health visit

Requires Mental Health Diagnosis (see below, Behavioral health section) and one of the following

  • E/M CPT codes 99201–99205 or 99211–99215
  • Psychiatry CPT codes (90801–90899)
  • Health Behavioral Assessment and Intervention (HBAI) CPT codes (96150–96155)
  • One of the following HCPCS codes
    • H0002
    • H0004
    • H0023-H0025
    • H0030-H0034
    • H0036-H0040
    • H0046
    • H2000-H2033
    • H2037
regexMH <- "(992[01][1-5])|(^908)|(9615[0-5])|((H0002)|(H0004)|(H002[3-5])|(H003[0-4])|(H003[6-9])|(H0040)|(H0046)|(^H20[0-2])|(H203[0-37]))"

4.6 Behavioral health

See Behavioral health definitions crosswalk.

5 different behavioral health indicators are created for each claim.

  1. Behavioral health, general
  2. Severe and persistent mental illness (SPMI)
  3. CMS hierarchical condition category (HCC)
    • Psychiatric
      • Schizophrenia
      • Major Depressive, Bipolar, and Paranoid Disorders
  4. HEDIS 2014 value set for Mental Illness
  5. HEDIS 2014 value set for Mental Health Diagnosis

Select the HEDIS Mental and Behavioral Disorders value set. Use this as a starting point. Indicators for subsets of these codes will be created. More codes will be added on. Verify that all the codes are ICD-9 diagnosis codes. Remove the . from the Code variable.

dfBH <- subset(dfHedisValueSets, Value.Set.Name == "Mental and Behavioral Disorders")
table(dfBH$codeSysVar)
## 
##        cpt     icd9cm    icd9pcs      loinc        drg        pos 
##          0        579          0          0          0          0 
##      ubRev typeOfBill 
##          0          0
dfBH$Code <- gsub("\\.", "", dfBH[dfBH$codeSysVar == "icd9cm", "Code"])

Create an indicator for Behavioral health, general.

regex1 <- "^29[1256789]|^30[0-9]|^31[0-6]"
regex2 <- "305[18]"
isBHGeneral <- intersect(grep(regex1, dfBH$Code), grep(regex2, dfBH$Code, invert=TRUE))
dfBH$isBHGeneral <- FALSE
dfBH$isBHGeneral[isBHGeneral] <- TRUE
rm(regex1, regex2, isBHGeneral)

Create an indicator for Severe and persistent mental illness (SPMI). SPMI is a subset of the codes for Behavioral health, general.

regex <- "^295|^2973|^2988|^2989|^296|^3003|30111|30113|30122|30183|30981"
isSPMI <- grep(regex, dfBH$Code)
dfBH$isSPMI <- FALSE
dfBH$isSPMI[isSPMI] <- TRUE
rm(regex, isSPMI)

Create an indicator for CMS HCC Psychiatric. Add E-codes for Suicide and self-inflicted injury; these are not part of the HEDIS Mental and Behavioral Disorders value set.

regex <- "^295|^296|^297"
isHCCPsychiatric <- grep(regex, dfBH$Code)
dfBH$isHCCPsychiatric <- FALSE
dfBH$isHCCPsychiatric[isHCCPsychiatric] <- TRUE
default <- cbind(Value.Set.Name = NA, 
                 Code.System = "ICD9CM", 
                 Definition = NA, 
                 codeSysVar = "icd9cm", 
                 isBHGeneral = FALSE, 
                 isSPMI = FALSE, 
                 isHCCPsychiatric = TRUE)
dfBH <- rbind(dfBH, data.frame(Code = c("E950", paste0("E950", c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))), default))
dfBH <- rbind(dfBH, data.frame(Code = c("E951", paste0("E951", c(0, 1,                   8   ))), default))
dfBH <- rbind(dfBH, data.frame(Code = c("E952", paste0("E952", c(0, 1,                   8, 9))), default))
dfBH <- rbind(dfBH, data.frame(Code = c("E953", paste0("E953", c(0, 1,                   8, 9))), default))
dfBH <- rbind(dfBH, data.frame(Code = c("E954",        "E954"                                  ), default))
dfBH <- rbind(dfBH, data.frame(Code = c("E955", paste0("E955", c(0, 1, 2, 3, 4, 5, 6, 7,    9))), default))
dfBH <- rbind(dfBH, data.frame(Code = c("E956",        "E956"                                  ), default))
dfBH <- rbind(dfBH, data.frame(Code = c("E957", paste0("E957", c(0, 1,                      9))), default))
dfBH <- rbind(dfBH, data.frame(Code = c("E958", paste0("E958", c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))), default))
dfBH <- rbind(dfBH, data.frame(Code = c("E959",        "E959"                                  ), default))
rm(regex, isHCCPsychiatric, default)

Create lists for HEDIS value set indicators lookups. All of these only use procedure codes and revenue codes, so use the helper function makeList.

lCodesMentalIllness <- makeList("Mental Illness")
## $valueSetName
## [1] "Mental Illness"
## 
## $summary
##         
##          Mental Illness
##   icd9cm            271
## 
## $cpt
## character(0)
## 
## $icd9cm
##   [1] "295"   "2950"  "29500" "29501" "29502" "29503" "29504" "29505"
##   [9] "2951"  "29510" "29511" "29512" "29513" "29514" "29515" "2952" 
##  [17] "29520" "29521" "29522" "29523" "29524" "29525" "2953"  "29530"
##  [25] "29531" "29532" "29533" "29534" "29535" "2954"  "29540" "29541"
##  [33] "29542" "29543" "29544" "29545" "2955"  "29550" "29551" "29552"
##  [41] "29553" "29554" "29555" "2956"  "29560" "29561" "29562" "29563"
##  [49] "29564" "29565" "2957"  "29570" "29571" "29572" "29573" "29574"
##  [57] "29575" "2958"  "29580" "29581" "29582" "29583" "29584" "29585"
##  [65] "2959"  "29590" "29591" "29592" "29593" "29594" "29595" "2960" 
##  [73] "29600" "296"   "29601" "29602" "29603" "29604" "29605" "29606"
##  [81] "29610" "2961"  "29611" "29612" "29613" "29614" "29615" "29616"
##  [89] "29620" "2962"  "29621" "29622" "29623" "29624" "29625" "29626"
##  [97] "29630" "2963"  "29631" "29632" "29633" "29634" "29635" "29636"
## [105] "2964"  "29640" "29641" "29642" "29643" "29644" "29645" "29646"
## [113] "2965"  "29650" "29651" "29652" "29653" "29654" "29655" "29656"
## [121] "2966"  "29660" "29661" "29662" "29663" "29664" "29665" "29666"
## [129] "2967"  "29680" "2968"  "29681" "29682" "29689" "2969"  "29690"
## [137] "29699" "297"   "2970"  "2971"  "2972"  "2973"  "2978"  "2979" 
## [145] "2980"  "298"   "2981"  "2982"  "2983"  "2984"  "2988"  "2989" 
## [153] "2990"  "29900" "299"   "29901" "2991"  "29910" "29911" "2998" 
## [161] "29980" "29981" "2999"  "29990" "29991" "3003"  "3004"  "3010" 
## [169] "301"   "3011"  "30110" "30111" "30112" "30113" "3012"  "30120"
## [177] "30121" "30122" "3013"  "3014"  "3015"  "30150" "30151" "30159"
## [185] "3016"  "3017"  "3018"  "30181" "30182" "30183" "30184" "30189"
## [193] "3019"  "308"   "3080"  "3081"  "3082"  "3083"  "3084"  "3089" 
## [201] "3090"  "309"   "3091"  "3092"  "30921" "30922" "30923" "30924"
## [209] "30928" "30929" "3093"  "3094"  "3098"  "30981" "30982" "30983"
## [217] "30989" "3099"  "311"   "312"   "3120"  "31200" "31201" "31202"
## [225] "31203" "3121"  "31210" "31211" "31212" "31213" "3122"  "31220"
## [233] "31221" "31222" "31223" "3123"  "31230" "31231" "31232" "31233"
## [241] "31234" "31235" "31239" "3124"  "3128"  "31281" "31282" "31289"
## [249] "3129"  "313"   "3130"  "3131"  "3132"  "31321" "31322" "31323"
## [257] "3133"  "3138"  "31381" "31382" "31383" "31389" "3139"  "3140" 
## [265] "314"   "31400" "31401" "3141"  "3142"  "3148"  "3149" 
## 
## $icd9pcs
## character(0)
## 
## $drg
## character(0)
## 
## $ubRev
## character(0)
## 
## $pos
## character(0)
## 
## $typeOfBill
## character(0)
lCodesMentalHealthDiagnosis <- makeList("Mental Health Diagnosis")
## $valueSetName
## [1] "Mental Health Diagnosis"
## 
## $summary
##         
##          Mental Health Diagnosis
##   icd9cm                     444
## 
## $cpt
## character(0)
## 
## $icd9cm
##   [1] "290"   "2900"  "2901"  "29010" "29011" "29012" "29013" "29020"
##   [9] "2902"  "29021" "2903"  "2904"  "29040" "29041" "29042" "29043"
##  [17] "2908"  "2909"  "2930"  "293"   "2931"  "2938"  "29381" "29382"
##  [25] "29383" "29384" "29389" "2939"  "2940"  "294"   "2941"  "29410"
##  [33] "29411" "2942"  "29420" "29421" "2948"  "2949"  "295"   "2950" 
##  [41] "29500" "29501" "29502" "29503" "29504" "29505" "2951"  "29510"
##  [49] "29511" "29512" "29513" "29514" "29515" "2952"  "29520" "29521"
##  [57] "29522" "29523" "29524" "29525" "2953"  "29530" "29531" "29532"
##  [65] "29533" "29534" "29535" "2954"  "29540" "29541" "29542" "29543"
##  [73] "29544" "29545" "2955"  "29550" "29551" "29552" "29553" "29554"
##  [81] "29555" "2956"  "29560" "29561" "29562" "29563" "29564" "29565"
##  [89] "2957"  "29570" "29571" "29572" "29573" "29574" "29575" "2958" 
##  [97] "29580" "29581" "29582" "29583" "29584" "29585" "2959"  "29590"
## [105] "29591" "29592" "29593" "29594" "29595" "2960"  "29600" "296"  
## [113] "29601" "29602" "29603" "29604" "29605" "29606" "29610" "2961" 
## [121] "29611" "29612" "29613" "29614" "29615" "29616" "29620" "2962" 
## [129] "29621" "29622" "29623" "29624" "29625" "29626" "29630" "2963" 
## [137] "29631" "29632" "29633" "29634" "29635" "29636" "2964"  "29640"
## [145] "29641" "29642" "29643" "29644" "29645" "29646" "2965"  "29650"
## [153] "29651" "29652" "29653" "29654" "29655" "29656" "2966"  "29660"
## [161] "29661" "29662" "29663" "29664" "29665" "29666" "2967"  "29680"
## [169] "2968"  "29681" "29682" "29689" "2969"  "29690" "29699" "297"  
## [177] "2970"  "2971"  "2972"  "2973"  "2978"  "2979"  "2980"  "298"  
## [185] "2981"  "2982"  "2983"  "2984"  "2988"  "2989"  "2990"  "29900"
## [193] "299"   "29901" "2991"  "29910" "29911" "2998"  "29980" "29981"
## [201] "2999"  "29990" "29991" "30000" "3000"  "300"   "30001" "30002"
## [209] "30009" "3001"  "30010" "30011" "30012" "30013" "30014" "30015"
## [217] "30016" "30019" "30020" "3002"  "30021" "30022" "30023" "30029"
## [225] "3003"  "3004"  "3005"  "3006"  "3007"  "3008"  "30081" "30082"
## [233] "30089" "3009"  "3010"  "301"   "3011"  "30110" "30111" "30112"
## [241] "30113" "3012"  "30120" "30121" "30122" "3013"  "3014"  "3015" 
## [249] "30150" "30151" "30159" "3016"  "3017"  "3018"  "30181" "30182"
## [257] "30183" "30184" "30189" "3019"  "3020"  "302"   "3021"  "3022" 
## [265] "3023"  "3024"  "3025"  "30250" "30251" "30252" "30253" "3026" 
## [273] "3027"  "30270" "30271" "30272" "30273" "30274" "30275" "30276"
## [281] "30279" "3028"  "30281" "30282" "30283" "30284" "30285" "30289"
## [289] "3029"  "3060"  "306"   "3061"  "3062"  "3063"  "3064"  "3065" 
## [297] "30650" "30651" "30652" "30653" "30659" "3066"  "3067"  "3068" 
## [305] "3069"  "3070"  "307"   "3071"  "30720" "3072"  "30721" "30722"
## [313] "30723" "3073"  "30740" "3074"  "30741" "30742" "30743" "30744"
## [321] "30745" "30746" "30747" "30748" "30749" "30750" "3075"  "30751"
## [329] "30752" "30753" "30754" "30759" "3076"  "3077"  "3078"  "30780"
## [337] "30781" "30789" "3079"  "308"   "3080"  "3081"  "3082"  "3083" 
## [345] "3084"  "3089"  "3090"  "309"   "3091"  "3092"  "30921" "30922"
## [353] "30923" "30924" "30928" "30929" "3093"  "3094"  "3098"  "30981"
## [361] "30982" "30983" "30989" "3099"  "3100"  "310"   "3101"  "3102" 
## [369] "3108"  "31081" "31089" "3109"  "311"   "312"   "3120"  "31200"
## [377] "31201" "31202" "31203" "3121"  "31210" "31211" "31212" "31213"
## [385] "3122"  "31220" "31221" "31222" "31223" "3123"  "31230" "31231"
## [393] "31232" "31233" "31234" "31235" "31239" "3124"  "3128"  "31281"
## [401] "31282" "31289" "3129"  "313"   "3130"  "3131"  "3132"  "31321"
## [409] "31322" "31323" "3133"  "3138"  "31381" "31382" "31383" "31389"
## [417] "3139"  "3140"  "314"   "31400" "31401" "3141"  "3142"  "3148" 
## [425] "3149"  "31500" "315"   "3150"  "31501" "31502" "31509" "3151" 
## [433] "3152"  "3153"  "31531" "31532" "31534" "31535" "31539" "3154" 
## [441] "3155"  "3158"  "3159"  "316"  
## 
## $icd9pcs
## character(0)
## 
## $drg
## character(0)
## 
## $ubRev
## character(0)
## 
## $pos
## character(0)
## 
## $typeOfBill
## character(0)

Create lookups for indicators that are not HEDIS value sets.

makeLookup <- function (name, indicator) {
  df <- dfBH[indicator == TRUE, ]
  t <- table(droplevels(df$codeSysVar))
  list(name = name,
       summary = t,
       icd9cm = df[df$codeSysVar == "icd9cm", "Code"])
}
lCodesBHGeneral <- makeLookup("Behavioral health, general", dfBH$isBHGeneral)
lCodesBHGeneral
## $name
## [1] "Behavioral health, general"
## 
## $summary
## 
## icd9cm 
##    535 
## 
## $icd9cm
##   [1] "2910"  "291"   "2911"  "2912"  "2913"  "2914"  "2915"  "2918" 
##   [9] "29181" "29182" "29189" "2919"  "2920"  "292"   "2921"  "29211"
##  [17] "29212" "2922"  "2928"  "29281" "29282" "29283" "29284" "29285"
##  [25] "29289" "2929"  "295"   "2950"  "29500" "29501" "29502" "29503"
##  [33] "29504" "29505" "2951"  "29510" "29511" "29512" "29513" "29514"
##  [41] "29515" "2952"  "29520" "29521" "29522" "29523" "29524" "29525"
##  [49] "2953"  "29530" "29531" "29532" "29533" "29534" "29535" "2954" 
##  [57] "29540" "29541" "29542" "29543" "29544" "29545" "2955"  "29550"
##  [65] "29551" "29552" "29553" "29554" "29555" "2956"  "29560" "29561"
##  [73] "29562" "29563" "29564" "29565" "2957"  "29570" "29571" "29572"
##  [81] "29573" "29574" "29575" "2958"  "29580" "29581" "29582" "29583"
##  [89] "29584" "29585" "2959"  "29590" "29591" "29592" "29593" "29594"
##  [97] "29595" "2960"  "29600" "296"   "29601" "29602" "29603" "29604"
## [105] "29605" "29606" "29610" "2961"  "29611" "29612" "29613" "29614"
## [113] "29615" "29616" "29620" "2962"  "29621" "29622" "29623" "29624"
## [121] "29625" "29626" "29630" "2963"  "29631" "29632" "29633" "29634"
## [129] "29635" "29636" "2964"  "29640" "29641" "29642" "29643" "29644"
## [137] "29645" "29646" "2965"  "29650" "29651" "29652" "29653" "29654"
## [145] "29655" "29656" "2966"  "29660" "29661" "29662" "29663" "29664"
## [153] "29665" "29666" "2967"  "29680" "2968"  "29681" "29682" "29689"
## [161] "2969"  "29690" "29699" "297"   "2970"  "2971"  "2972"  "2973" 
## [169] "2978"  "2979"  "2980"  "298"   "2981"  "2982"  "2983"  "2984" 
## [177] "2988"  "2989"  "2990"  "29900" "299"   "29901" "2991"  "29910"
## [185] "29911" "2998"  "29980" "29981" "2999"  "29990" "29991" "30000"
## [193] "3000"  "300"   "30001" "30002" "30009" "3001"  "30010" "30011"
## [201] "30012" "30013" "30014" "30015" "30016" "30019" "30020" "3002" 
## [209] "30021" "30022" "30023" "30029" "3003"  "3004"  "3005"  "3006" 
## [217] "3007"  "3008"  "30081" "30082" "30089" "3009"  "3010"  "301"  
## [225] "3011"  "30110" "30111" "30112" "30113" "3012"  "30120" "30121"
## [233] "30122" "3013"  "3014"  "3015"  "30150" "30151" "30159" "3016" 
## [241] "3017"  "3018"  "30181" "30182" "30183" "30184" "30189" "3019" 
## [249] "3020"  "302"   "3021"  "3022"  "3023"  "3024"  "3025"  "30250"
## [257] "30251" "30252" "30253" "3026"  "3027"  "30270" "30271" "30272"
## [265] "30273" "30274" "30275" "30276" "30279" "3028"  "30281" "30282"
## [273] "30283" "30284" "30285" "30289" "3029"  "3030"  "30300" "303"  
## [281] "30301" "30302" "30303" "3039"  "30390" "30391" "30392" "30393"
## [289] "304"   "3040"  "30400" "30401" "30402" "30403" "3041"  "30410"
## [297] "30411" "30412" "30413" "3042"  "30420" "30421" "30422" "30423"
## [305] "3043"  "30430" "30431" "30432" "30433" "3044"  "30440" "30441"
## [313] "30442" "30443" "3045"  "30450" "30451" "30452" "30453" "3046" 
## [321] "30460" "30461" "30462" "30463" "3047"  "30470" "30471" "30472"
## [329] "30473" "3048"  "30480" "30481" "30482" "30483" "3049"  "30490"
## [337] "30491" "30492" "30493" "3050"  "30500" "305"   "30501" "30502"
## [345] "30503" "3052"  "30520" "30521" "30522" "30523" "3053"  "30530"
## [353] "30531" "30532" "30533" "3054"  "30540" "30541" "30542" "30543"
## [361] "3055"  "30550" "30551" "30552" "30553" "3056"  "30560" "30561"
## [369] "30562" "30563" "3057"  "30570" "30571" "30572" "30573" "3059" 
## [377] "30590" "30591" "30592" "30593" "3060"  "306"   "3061"  "3062" 
## [385] "3063"  "3064"  "3065"  "30650" "30651" "30652" "30653" "30659"
## [393] "3066"  "3067"  "3068"  "3069"  "3070"  "307"   "3071"  "30720"
## [401] "3072"  "30721" "30722" "30723" "3073"  "30740" "3074"  "30741"
## [409] "30742" "30743" "30744" "30745" "30746" "30747" "30748" "30749"
## [417] "30750" "3075"  "30751" "30752" "30753" "30754" "30759" "3076" 
## [425] "3077"  "3078"  "30780" "30781" "30789" "3079"  "308"   "3080" 
## [433] "3081"  "3082"  "3083"  "3084"  "3089"  "3090"  "309"   "3091" 
## [441] "3092"  "30921" "30922" "30923" "30924" "30928" "30929" "3093" 
## [449] "3094"  "3098"  "30981" "30982" "30983" "30989" "3099"  "3100" 
## [457] "310"   "3101"  "3102"  "3108"  "31081" "31089" "3109"  "311"  
## [465] "312"   "3120"  "31200" "31201" "31202" "31203" "3121"  "31210"
## [473] "31211" "31212" "31213" "3122"  "31220" "31221" "31222" "31223"
## [481] "3123"  "31230" "31231" "31232" "31233" "31234" "31235" "31239"
## [489] "3124"  "3128"  "31281" "31282" "31289" "3129"  "313"   "3130" 
## [497] "3131"  "3132"  "31321" "31322" "31323" "3133"  "3138"  "31381"
## [505] "31382" "31383" "31389" "3139"  "3140"  "314"   "31400" "31401"
## [513] "3141"  "3142"  "3148"  "3149"  "31500" "315"   "3150"  "31501"
## [521] "31502" "31509" "3151"  "3152"  "3153"  "31531" "31532" "31534"
## [529] "31535" "31539" "3154"  "3155"  "3158"  "3159"  "316"
lCodesSPMI <- makeLookup("Severe and persistent mental illness (SPMI)", dfBH$isSPMI)
lCodesSPMI
## $name
## [1] "Severe and persistent mental illness (SPMI)"
## 
## $summary
## 
## icd9cm 
##    146 
## 
## $icd9cm
##   [1] "295"   "2950"  "29500" "29501" "29502" "29503" "29504" "29505"
##   [9] "2951"  "29510" "29511" "29512" "29513" "29514" "29515" "2952" 
##  [17] "29520" "29521" "29522" "29523" "29524" "29525" "2953"  "29530"
##  [25] "29531" "29532" "29533" "29534" "29535" "2954"  "29540" "29541"
##  [33] "29542" "29543" "29544" "29545" "2955"  "29550" "29551" "29552"
##  [41] "29553" "29554" "29555" "2956"  "29560" "29561" "29562" "29563"
##  [49] "29564" "29565" "2957"  "29570" "29571" "29572" "29573" "29574"
##  [57] "29575" "2958"  "29580" "29581" "29582" "29583" "29584" "29585"
##  [65] "2959"  "29590" "29591" "29592" "29593" "29594" "29595" "2960" 
##  [73] "29600" "296"   "29601" "29602" "29603" "29604" "29605" "29606"
##  [81] "29610" "2961"  "29611" "29612" "29613" "29614" "29615" "29616"
##  [89] "29620" "2962"  "29621" "29622" "29623" "29624" "29625" "29626"
##  [97] "29630" "2963"  "29631" "29632" "29633" "29634" "29635" "29636"
## [105] "2964"  "29640" "29641" "29642" "29643" "29644" "29645" "29646"
## [113] "2965"  "29650" "29651" "29652" "29653" "29654" "29655" "29656"
## [121] "2966"  "29660" "29661" "29662" "29663" "29664" "29665" "29666"
## [129] "2967"  "29680" "2968"  "29681" "29682" "29689" "2969"  "29690"
## [137] "29699" "2973"  "2988"  "2989"  "3003"  "30111" "30113" "30122"
## [145] "30183" "30981"
lCodesHCCPsychiatric <- makeLookup("CMS hierarchical condition category (HCC) Psychiatric", dfBH$isHCCPsychiatric)
lCodesHCCPsychiatric
## $name
## [1] "CMS hierarchical condition category (HCC) Psychiatric"
## 
## $summary
## 
## icd9cm 
##    200 
## 
## $icd9cm
##   [1] "295"   "2950"  "29500" "29501" "29502" "29503" "29504" "29505"
##   [9] "2951"  "29510" "29511" "29512" "29513" "29514" "29515" "2952" 
##  [17] "29520" "29521" "29522" "29523" "29524" "29525" "2953"  "29530"
##  [25] "29531" "29532" "29533" "29534" "29535" "2954"  "29540" "29541"
##  [33] "29542" "29543" "29544" "29545" "2955"  "29550" "29551" "29552"
##  [41] "29553" "29554" "29555" "2956"  "29560" "29561" "29562" "29563"
##  [49] "29564" "29565" "2957"  "29570" "29571" "29572" "29573" "29574"
##  [57] "29575" "2958"  "29580" "29581" "29582" "29583" "29584" "29585"
##  [65] "2959"  "29590" "29591" "29592" "29593" "29594" "29595" "2960" 
##  [73] "29600" "296"   "29601" "29602" "29603" "29604" "29605" "29606"
##  [81] "29610" "2961"  "29611" "29612" "29613" "29614" "29615" "29616"
##  [89] "29620" "2962"  "29621" "29622" "29623" "29624" "29625" "29626"
##  [97] "29630" "2963"  "29631" "29632" "29633" "29634" "29635" "29636"
## [105] "2964"  "29640" "29641" "29642" "29643" "29644" "29645" "29646"
## [113] "2965"  "29650" "29651" "29652" "29653" "29654" "29655" "29656"
## [121] "2966"  "29660" "29661" "29662" "29663" "29664" "29665" "29666"
## [129] "2967"  "29680" "2968"  "29681" "29682" "29689" "2969"  "29690"
## [137] "29699" "297"   "2970"  "2971"  "2972"  "2973"  "2978"  "2979" 
## [145] "E950"  "E9500" "E9501" "E9502" "E9503" "E9504" "E9505" "E9506"
## [153] "E9507" "E9508" "E9509" "E951"  "E9510" "E9511" "E9518" "E952" 
## [161] "E9520" "E9521" "E9528" "E9529" "E953"  "E9530" "E9531" "E9538"
## [169] "E9539" "E954"  "E954"  "E955"  "E9550" "E9551" "E9552" "E9553"
## [177] "E9554" "E9555" "E9556" "E9557" "E9559" "E956"  "E956"  "E957" 
## [185] "E9570" "E9571" "E9579" "E958"  "E9580" "E9581" "E9582" "E9583"
## [193] "E9584" "E9585" "E9586" "E9587" "E9588" "E9589" "E959"  "E959"

4.7 NDC

Import the NDC translation dataset. See the queryRxClaims repository on GitHub for details.

url <- "https://raw.githubusercontent.com/benjamin-chan/NDCTranslation/TextFile/NDCTranslationTable.txt"
ndcMaster <- fread(url, colClasses=rep("character", 22))
## 
Read 45.2% of 154698 rows
Read 58.2% of 154698 rows
Read 97.0% of 154698 rows
Read 154698 rows and 22 (of 22) columns from 0.060 GB file in 00:00:05

4.8 Helper functions

checkIndicator <- function (D, x) {
  tab <- D[isSample1 == TRUE, 
           .N, 
           list(var = get(x))]
  tab <- tab[, prop := sprintf("%.1f%%", N / sum(N) * 100)]
  tab <- tab[order(var)]
  setnames(tab, "var", x)
  tab
}

4.9 Save helper objects

Bundle the helper objects to a file for later use.

f <- sprintf("%s\\%s", pathTemp, "helpers.RData")
metadata <- makeMetadata("makeHelpers.Rmd")
objNames <- c("validValues",
              "lBatchDocType",
              "lClaimType",
              "codeBetos",
              "facBetos",
              "dfHedisValueSets",
              "dfBH",
              "regexPCP",
              "regexMH",
              "lCodesAcuteInpatient",
              "lCodesNonacuteInpatient",
              "lCodesIPUExclusionsDRG",
              "lCodesMaternityDRG",
              "lCodesSurgeryDRG",
              "lCodesMedicineDRG",
              "lCodesNewbornsDRG",
              "lCodesMaternityDiagnosis",
              "lCodesMaternity",
              "lCodesSurgery",
              "lCodesObservation",
              "lCodesED",
              "lCodesEDProcedureCode",
              "lCodesEDPOS",
              "lCodesOutpatient",
              "lCodesAmbulatoryOutpatient",
              "lCodesDetox",
              "lCodesPregnancy",
              "lCodesOutpatientExpanded",
              "lCodesMentalIllness",
              "lCodesMentalHealthDiagnosis",
              "lCodesBHGeneral",
              "lCodesSPMI",
              "lCodesHCCPsychiatric",
              "ndcMaster",
              "checkIndicator")
save(list=c("metadata", "objNames", objNames), file=f)
file.info(f)[c("size", "mtime")]
##                                                              size
## E:\\Share\\Temp\\chanb\\Colorado Medicaid\\helpers.RData 14907116
##                                                                        mtime
## E:\\Share\\Temp\\chanb\\Colorado Medicaid\\helpers.RData 2015-07-17 15:56:58

5 Client snapshot

The Colorado client snapshot is the analog to the Medicaid recipient dataset and the APAC enrollment dataset. The client snapshot data is structured similarly to the APAC enrollment dataset. The data contains one row per client per month. Each month is referred to as a snapshot period.

The key variables in the pre-staged client snapshot dataset are

Keep only enrollment records for clients who were

From: Lindrooth, Richard [mailto:RICHARD.LINDROOTH@UCDENVER.EDU]   
Sent: Thursday, March 19, 2015 4:16 PM  
To: Benjamin Chan; John McConnell; Duke, Jodi Kay  
Cc: Stephanie Renfro  
Subject: Re: ACC eligibility  

Ben,  I think it makes sense to go with the definition constructed ourselves.
It will allow us to consistently define the population over the entire period.
It isn't possible to identify the folks who would be eligible in the pre-
period using the definition provided in the data.

What do you guys think?  I'd prefer to be consistent across papers since some
may use pre-period data.  I'd prefer to stick with one and use it regardless
of whether the CO pre-period dataset is needed.

One potential difficulty is that the levels of the variables required to
generate our definition are not consistent over time.  Jodi is looking into
that.  Even so, we can probably come pretty close.

We will also need to differentiate between the expansion populations and the
standard populations.  The expansion population will not be possible to
identify in the pre-period but we can use the definition when matching to
Oregon's expansion population.

We can ask HCPF about the "weird bumps"  on our call.  As you state we might
be missing some info.
From: Lindrooth, Richard [mailto:RICHARD.LINDROOTH@UCDENVER.EDU] 
Sent: Thursday, July 02, 2015 3:58 PM
To: Benjamin Chan
Subject: RE: ACC State Reports

Most of the following dropped out when I limited to regular Medicaid: 

clm_type_cd=="M"  "Part A xover"
clm_type_cd=="N"  "Part B xover"
clm_type_cd=="O"  "Part A & B xover"


Where regular Medicaid is:

Clnt_elig_type_cd==4, 5, 6, 7, 8, 17 (FFS but enhanced services) 
system.time(callSAS("makeClientSnapshot.sas", path=pathScripts))
## Warning: running command '"C:\Program Files\SASHome\SASFoundation
## \9.3\sas.exe" -sysin "H:/CHSE/Projects/DataProcessing/ColoradoMedicaid/
## StagingCode\makeClientSnapshot.sas" -log "H:/CHSE/Projects/
## DataProcessing/ColoradoMedicaid/StagingCode\makeClientSnapshot.log" -
## print "H:/CHSE/Projects/DataProcessing/ColoradoMedicaid/StagingCode
## \makeClientSnapshot.log" -work "E:\Share\Temp\chanb\SASWork"' had status 1
## /* 
## Set library paths.
## Set options.
##  */
## %let pathData = E:\Share\DataRepository\Colorado Medicaid;
## libname PreSt "&pathData\PreStaged" access=readonly;
## libname Staged "&pathData\Staged";
## options fmtsearch = (Staged);
## options formchar="|----|+|---+=|-/\<>*";
## options ls=132 ps=max;
## 
## 
## /* 
## Show contents of prestaging datasets
##  */
## proc contents data=PreSt.clientSnapshot order=varnum;
## run;
## 
## 
## /* 
## MAIN QUERY
##  */
## 
## proc sql;
##   create table Work.clientSnapshot as 
##   select
##     A.CLNT_ID,
##     "D" || A.CLNT_ID      as memberID,
##     B.Snapshot_Beg_Dt     as dateCoverageBegin,
##     B.Snapshot_End_Dt     as dateCoverageEnd,
##     A.CLNT_AGE            as age,
##     A.CLNT_GENDER_CD      as gender,
##     A.CLNT_CASE_ZIP_5_NUM as memberZip,
##     ""                    as memberZipDesig,
##     A.CLNT_CNTY_CD        as memberCounty,
##     ""                    as memberMSA,
##     A.CLNT_RACE_CD        as race,
##     A.ACC_ELIGIBLE_IND,
##     A.Snapshot_Period_ID,
## /* 
## > From: Duke, Jodi Kay [mailto:Jodi.Duke@ucdenver.edu]   
## > Sent: Tuesday, April 21, 2015 7:49 AM  
## > To: Benjamin Chan  
## > Subject: Quick Question about Timing for ACC  
## 
## > Hi Ben --- Just a quick note/question.  I'm using these for the year cutoffs.
## > Is this what you are using? (a `[` is inclusive of the period)
## 
## > Pre-ACC Program:  [Period 1 to Period 22]  
## > Year 1 Program:  [Period 23 to Period 36]  
## > Year 2 Program:  [Period 37 to Period 48]  
## > Year 3 Program:  [Period 49 to Period 60]  
## > Year 4 Program:  [Period 61 to Period 64]  
##  */
##     case
##       when A.Snapshot_Period_ID < 23 then "Pre ACC"
##       when 23 <= A.Snapshot_Period_ID <= 36 then "Year 1"
##       when 37 <= A.Snapshot_Period_ID <= 48 then "Year 2"
##       when 49 <= A.Snapshot_Period_ID <= 60 then "Year 3"
##       when 61 <= A.Snapshot_Period_ID <= 64 then "Year 4"
##       else ""
##       end as accPeriod,
##     A.RG_ELIG_Cd,
##     A.RG_STTG_Cd,
##     A.RG_PROG_Cd,
##     A.RG_TPL_Cd ,
##     A.CLNT_ELIG_TYPE_CD,
## /* 
## From: Duke, Jodi Kay [mailto:Jodi.Duke@ucdenver.edu] 
## Sent: Monday, May 25, 2015 7:27 PM
## To: Benjamin Chan
## Subject: Data Flow Chart
##  
## OK, I've been playing around and feel pretty comfortable with this.  I'd like to
## confirm what I've done with HCPF but here's the low-down:
## 
## Nothing changed with the HCPF hierarchy: Dual Demo > Expansion > Dual Non-Demo > Standard > Other
## Step 1: From that hierarchy, keep Duals, Expn, Stnd
##  */
##     case
##       when
##         prxmatch("/[02]3/", A.CLNT_TPL_CD) > 0 &
##           prxmatch("/00[1-8]/", A.CLNT_ELIG_TYPE_CD) > 0 &
##           A.MANAGED_CARE_IND = 0 &
##           A.CPCI_ENRL_IND = 0
##         then "DEMO"
##       when
##         A.CLNT_ELIG_TYPE_CD = "030" &
##           A.CLNT_TPL_CD = "00" &
##           A.XOVER_IND = 0
##         then "EXPN"
##       when
##         (prxmatch("/(0[124-9])|(1[0-9])|(2[012456])/", A.CLNT_TPL_CD) > 0) |
##           (prxmatch("/[02]3/", A.CLNT_TPL_CD) > 0 & prxmatch("/00[1-8]/", A.CLNT_ELIG_TYPE_CD) = 0) |
##           (prxmatch("/[02]3/", A.CLNT_TPL_CD) > 0 & A.MANAGED_CARE_IND = 1) |
##           (prxmatch("/[02]3/", A.CLNT_TPL_CD) > 0 & A.CPCI_ENRL_IND = 1) |
##           XOVER_IND = 1
##         then "NDEM"
##       when
##         prxmatch("/(00[1-8])|(0((15)|(20)|(31)|(32)))/", A.CLNT_ELIG_TYPE_CD) > 0 &
##           A.CLNT_TPL_CD = "00" &
##           A.XOVER_IND = 0
##         then "STND"
##       else "OTHR"
##       end as myEligibility,
##     case
##       when A.MHI_IND = 1
##         then "MHI"
##       when A.SNF_IND = 1
##         then "SNF"
##       when A.WAIVER_IND = 1
##         then "WVR"
##       else "CWLL"
##       end as mySetting,
##     case
##       when
##         A.RCO_ENROLLED_IND = 1
##         then "ACC"
##       when
##         A.MANAGED_CARE_IND = 1
##         then "MC"
##       else "FFS"
##       end as myProgram,
##     case
##       when
##         A.CLNT_TPL_CD = "00"
##         then "MCON"
##       when
##         prxmatch("/[02]3/", A.CLNT_TPL_CD) > 0
##         then "MRDM"
##       when
##         prxmatch("/(0[124-9])|(1[0-9])|(2[012456])/", A.CLNT_TPL_CD) > 0
##         then "MRND"
##       else "OTHR"
##       end as myTPL,
## /* 
## Step 2: Created groups based on the rg_sttg_cd, tpl, and rg_prog_cd
## 
## Group 1: Standard Eligibles
## gen my_stnd_elig_for_step2=my_stnd==1 & (rg_sttg_cd=="WVR" | rg_sttg_cd=="CWLL") & (rg_prog_cd=="FFS" | rg_prog_cd=="ACC") & (my_tpl==1)
## 
## Group 2: ACA Expansion Eligibles (starting in Period 55)
## gen my_ACA_expn_for_STEP2=my_expn==1 & (clnt_elig_type_cd==004 | clnt_elig_type_cd==030) & (clnt_benchmark_id_cd=="BA" | clnt_benchmark_id_cd=="BB" | clnt_benchmark_id_cd=="BC" | clnt_benchmark_id_cd=="BD" | clnt_benchmark_id_cd=="BF" | clnt_benchmark_id_cd=="BG") & snapshot_period_id>54
## 
## Group 3: Regular Expansion prior to ACA (prior to Period 55)
## gen my_expn_elig_for_STEP2A=my_expn==1 & (rg_sttg_cd=="WVR" | rg_sttg_cd=="CWLL") & (rg_prog_cd=="FFS" | rg_prog_cd=="ACC") & (my_tpl==1) & snapshot_period_id<55
## 
## Group 4: Regular Expanion after ACA (beginning Period 55)
## gen my_expn_elig_for_STEP2B=my_expn==1 & (rg_sttg_cd=="WVR" | rg_sttg_cd=="CWLL") & (rg_prog_cd=="FFS" | rg_prog_cd=="ACC") & (my_tpl==1) & snapshot_period_id>54 & my_ACA_expn_for_STEP2 !=1
## 
## Group 5: Dual Demos ***DROP THIS GROUP
## gen my_dualdemo_elig_for_step2=my_dualdemo==1 & (rg_sttg_cd=="WVR" | rg_sttg_cd=="CWLL" | rg_sttg_cd=="SNF" | rg_sttg_cd=="MHI") & (rg_prog_cd=="FFS" | rg_prog_cd=="ACC") & (rg_tpl_cd=="MCON" | rg_tpl_cd=="MRDM") & snapshot_period_id>=63
##  */
##     case
##       when
##         calculated myEligibility in ("STND") &
##           calculated mySetting in ("WVR", "CWLL") &
##           calculated myProgram in ("ACC", "FFS") &
##           calculated myTPL in ("MCON")
##         then "Standard"
##       when
##         A.Snapshot_Period_ID >= 55 &
##           calculated myEligibility in ("EXPN") &
##           A.CLNT_ELIG_TYPE_CD in ("004", "030") &
##           prxmatch("/^B[ABCDFG]$/", A.clnt_benchmark_id_cd) > 0
##         then "ACA Expansion"
##       when
##         A.Snapshot_Period_ID < 55 &
##           calculated myEligibility in ("EXPN") &
##           calculated mySetting in ("WVR", "CWLL") &
##           calculated myProgram in ("ACC", "FFS") &
##           calculated myTPL in ("MCON")
##         then "Regular Expansion pre-ACA"
##       when
##         A.Snapshot_Period_ID >= 55 &
##           calculated myEligibility in ("EXPN") &
##           calculated mySetting in ("WVR", "CWLL") &
##           calculated myProgram in ("ACC", "FFS") &
##           calculated myTPL in ("MCON")
##         then "Regular Expansion post-ACA"
##       when
##         A.Snapshot_Period_ID >= 63 & 
##           calculated myEligibility in ("DEMO") &
##           calculated mySetting in ("MHI", "SNF", "WVR", "CWLL") &
##           calculated myProgram in ("ACC", "FFS") &
##           calculated myTPL in ("MCON", "MRDM")
##         then "Dual demo"
##       else "Not eligible"
##       end as flagEligibility,
##     calculated flagEligibility = "Standard" as isEligibleStnd,
##     calculated flagEligibility = "ACA Expansion" as isEligibleACAExpn,
##     calculated flagEligibility = "Regular Expansion pre-ACA" as isEligibleRegExpnPreACA,
##     calculated flagEligibility = "Regular Expansion post-ACA" as isEligibleRegExpnPostACA,
##     calculated flagEligibility = "Dual demo" as isEligibleDualDemo,
##     A.RCO_ENROLLED_IND,
##     A.RCO_MC_ENROL_STAT_CD,
##     A.RCO_MC_ENROL_TYPE_CD,
##     A.RCO_PROV_ID,
##     A.RCO_MC_ENROL_DIS_RSN_CD,
##     A.PCM_ENROLLED_IND,
##     A.PCM_MC_ENROL_STAT_CD,
##     A.PCM_MC_ENROL_TYPE_CD,
##     A.PCM_PROV_ID,
##     A.PCM_MC_ENROL_DIS_RSN_CD,
##     A.PCM_TYPE_CD,
##     A.CLNT_GENDER_CD = "F" & 13 <= A.CLNT_AGE <= 66 as isChildBearingAge,
##     A.CLNT_AGE > 64 as isAgeOver64,
##     A.isSample1,
##     A.isSample5,
##     A.DHMCP_IND,
##     A.MANAGED_CARE_IND,
##     A.ACC_OPT_OUT_IND,
##     A.ACC_LOCK_OUT_IND,
##     A.CLNT_REGION_ID,
##     A.RCO_RCCO_ID,
## /* 
## For Step 3 --- Defining the POST RCCO Eligibles (beginning in Period 23):
## Starting with STEP 2 clients, I then excluded those with a MC indicator, DH Indicator, Clnt Region 0 Indicator, RCCO Region 0 Indicator, or Mesa County Indicator
## gen my_step3_CCO_POST_Eligibles=my_step2 if snapshot_period_id>22
## replace my_step3_CCO_POST_Eligibles=0 if my_managed_care_ind==1 & snapshot_period_id>22
## replace my_step3_CCO_POST_Eligibles=0 if my_rco_enroll_clntreg0_ind==1 & snapshot_period_id>22
## replace my_step3_CCO_POST_Eligibles=0 if my_rco_enroll_rccoreg0_ind==1 & snapshot_period_id>22
## replace my_step3_CCO_POST_Eligibles=0 if my_rco_enroll_mesa_ind==1 & snapshot_period_id>22
## replace my_step3_CCO_POST_Eligibles=0 if my_dhmcp_ind==1 & snapshot_period_id>22
## 
## For Step 4 --- Defining the PRE RCCO Eligibles (prior to Period 23):
## Starting with STEP 2 clients, I then excludeed those with HCPF indicators for Mesa County, Denver Health, and Managed Care
## gen my_step4_PRE_eligibles=my_step2 if snapshot_period_id<23 
## replace my_step4_PRE_eligibles=0 if dhmcp_ind==1 & snapshot_period_id<23
## replace my_step4_PRE_eligibles=0 if clnt_cnty_cd==39 & snapshot_period_id<23
## replace my_step4_PRE_eligibles=0 if managed_care_ind==1 & snapshot_period_id<23
##  */
## 
## /* 
## From: Lindrooth, Richard [mailto:RICHARD.LINDROOTH@UCDENVER.EDU] 
## Sent: Thursday, July 02, 2015 3:58 PM
## To: Benjamin Chan
## Subject: RE: ACC State Reports
## 
## Most of the following dropped out when I limited to regular Medicaid: 
## 
## clm_type_cd=="M"  "Part A xover"
## clm_type_cd=="N"  "Part B xover"
## clm_type_cd=="O"  "Part A & B xover"
## 
## 
## Where regular Medicaid is:
## 
## Clnt_elig_type_cd==4, 5, 6, 7, 8, 17 (FFS but enhanced services) 
##  */
##     case
##       when
##         calculated flagEligibility in ("Not eligible", "Dual demo")
##         then 1
##       when
##         A.snapshot_period_id >= 23 &
##           A.RCO_MC_ENROL_TYPE_CD = "RCO" &
##           (A.DHMCP_IND | 
##            A.MANAGED_CARE_IND |
##            put(A.CLNT_CNTY_CD, $CT.) = "MESA" |
##            A.CLNT_REGION_ID = 0 | 
##            A.RCO_RCCO_ID = 0)
##         then 1
##       when
##         A.snapshot_period_id < 23 &
##           (A.DHMCP_IND | 
##            A.MANAGED_CARE_IND |
##            put(A.CLNT_CNTY_CD, $CT.) = "MESA")
##         then 1
##       when
##         prxmatch("/0((0[4-8])|(17))/", A.CLNT_ELIG_TYPE_CD) <= 0
##         then 1
##       else 0
##       end as isExclude
##   from
##     (select * from PreSt.clientSnapshot /* where isSample1 */) A left join
##       (select Snapshot_Period_ID, datepart(Snapshot_Beg_Dt) as Snapshot_Beg_Dt, datepart(Snapshot_End_Dt) as Snapshot_End_Dt from PreSt.SnapshotPeriodDefinition) B on
##       (A.Snapshot_Period_ID = B.Snapshot_Period_ID) inner join
##       (select CLNT_ID, count(*) as countMemberMonths from PreSt.clientSnapshot group by CLNT_ID) C on
##       (A.CLNT_ID = C.CLNT_ID)
##   ;
##   title1 "Validation checks BEFORE Exclusions";
##   select
##     A.myEligibility,
##     put(min(A.Snapshot_Period_ID), 2.) || "-" || put(max(A.Snapshot_Period_ID), 2.) as rangeSnapshotPeriods,
##     count(*) format=comma12.0 as countRows,
##     count(*) / (select count(*) from Work.clientSnapshot) format=percent10.2 as propRows
##   from
##     Work.clientSnapshot A
##   group by
##     myEligibility
##   ;
##   select
##     A.accPeriod,
##     put(min(A.Snapshot_Period_ID), 2.) || "-" || put(max(A.Snapshot_Period_ID), 2.) as rangeSnapshotPeriods,
##     count(*) format=comma12.0 as countRows,
##     count(*) / (select count(*) from Work.clientSnapshot) format=percent10.2 as propRows
##   from
##     Work.clientSnapshot A
##   group by
##     accPeriod
##   ;
##   select
##     A.isEligibleStnd,
##     A.isEligibleACAExpn,
##     A.isEligibleRegExpnPreACA,
##     A.isEligibleRegExpnPostACA,
##     A.isEligibleDualDemo,
##     A.flagEligibility,
##     put(min(A.Snapshot_Period_ID), 2.) || "-" || put(max(A.Snapshot_Period_ID), 2.) as rangeSnapshotPeriods,
##     count(*) format=comma12.0 as countRows,
##     count(*) / (select count(*) from Work.clientSnapshot) format=percent10.2 as propRows
##   from
##     Work.clientSnapshot A
##   group by
##     A.isEligibleStnd,
##     A.isEligibleACAExpn,
##     A.isEligibleRegExpnPreACA,
##     A.isEligibleRegExpnPostACA,
##     A.isEligibleDualDemo,
##     A.flagEligibility
##   ;
##   select
##     case
##       when missing(isExclude) then ""
##       when isExclude then "Exclude"
##       when not(isExclude) then "Include"
##       else ""
##       end as include,
##     case
##       when missing(A.accPeriod) then ""
##       when A.accPeriod = "Pre ACC" then "Pre"
##       when A.accPeriod ^= "Pre ACC" then "Post"
##       else ""
##       end as period,
##     put(min(A.Snapshot_Period_ID), 2.) || "-" || put(max(A.Snapshot_Period_ID), 2.) as rangeSnapshotPeriods,
##     count(*) format=comma12.0 as countRows,
##     count(*) / (select count(*) from Work.clientSnapshot) format=percent10.2 as propRows
##   from
##     Work.clientSnapshot A
##   group by
##     calculated include,
##     calculated period
##   ;
##   title1 "Make exclusions and write to permanent library";
##   create table Staged.clientSnapshot as
##   select
##     A.*
##   from
##     Work.clientSnapshot A
##   where
##     not(isExclude)
##   ;
##   alter table Staged.clientSnapshot
##   drop isExclude
##   ;
##   title1;
## quit;
## 
## 
## /* 
## Double check my numbers
##  */
## proc sql;
##   select
##     A.accPeriod,
##     put(min(A.Snapshot_Period_ID), 2.) || "-" || put(max(A.Snapshot_Period_ID), 2.) as rangeSnapshotPeriods,
##     count(*) format=comma12.0 as countRows,
##     count(*) / (select count(*) from Staged.clientSnapshot) format=percent10.2 as propRows
##   from
##     Staged.clientSnapshot A
##   group by
##     A.accPeriod
##   ;
## quit;
## 
## 
## /* 
## Check sampling indicators
##  */
## proc sql;
##   select
##     isSample1,
##     isSample5,
##     count(*) format=comma20. as countRows,
##     count(*) / (select count(*) from Staged.clientSnapshot) format=percent10.2 as propRows
##   from
##     Staged.clientSnapshot
##   group by
##     isSample1,
##     isSample5
##   ;
## quit;
## 
## 
## /* 
## Make indexes
##  */
## proc datasets library=Staged;
##   modify clientSnapshot;
##   index create dateCoverageBegin;
##   index create memberID;
##   index create key = (memberID dateCoverageBegin) / unique;
##   format dateCoverageBegin dateCoverageEnd yymmdd10.;
##   format gender $1.;
## run;
## 
## 
## /* 
## Make colClasses dataset.
## Output for later use in R.
##  */
## proc contents data=Staged.clientSnapshot order=varnum out=Work.contents;
## run;
## proc sql;
##   create table Work.colClasses as
##   select
##     varnum,
##     case
##       when prxmatch("/\$/", format) then "character"
##       when prxmatch("/YYMMDD/", format) then "character"
##       when formatd > 0 then "numeric"
##       else "integer"
##     end as colClass
##   from Work.contents
##   order by
##     varnum
##   ;
## quit;
## 
## 
## /* 
## Export datasets to CSV files for later use in R
##  */
## filename f "&pathData\Staged\clientSnapshot.csv";
## proc export data=Staged.clientSnapshot outfile=f dbms=csv replace;
## run;
## filename f "&pathData\Staged\colClasses.csv";
## proc export data=Work.colClasses outfile=f dbms=csv replace;
## run;
## No errors
## See H:/CHSE/Projects/DataProcessing/ColoradoMedicaid/StagingCode\makeClientSnapshot.log for details.
##    user  system elapsed 
##    0.02    0.02 1147.89

5.1 Read data file

f <- sprintf("%s\\colClasses.csv", pathStaged)
colClasses <- fread(f)
file.remove(f)
## [1] TRUE
f <- sprintf("%s\\clientSnapshot.csv", pathStaged)
D0 <- fread(f, colClasses=colClasses[, colClass], na.strings=na.strings, showProgress=FALSE)
# D0 <- D0[isSample1 == TRUE]  # Uncomment this line for testing
D0 <- D0[, Snapshot_Period_ID := NULL]
D0 <- D0[,
         `:=` (dateCoverageBegin = as.Date(dateCoverageBegin),
               dateCoverageEnd = as.Date(dateCoverageEnd))]
# str(D0)

5.2 Correct age variable

Rich discovered that the age variable from the client snapshot file has problems. Values are inconsistent within client. He created a Stata 13 dataset containing the following variables

  • snapshot_period_id
  • clnt_id
  • clnt_age

Open Rich’s dataset.

f <- sprintf("%s\\%s\\%s", pathData, "PreStaged", "CleanAge13.dta")
file.info(f)
##                                                                              size
## E:\\Share\\DataRepository\\Colorado Medicaid\\PreStaged\\CleanAge13.dta 518084338
##                                                                         isdir
## E:\\Share\\DataRepository\\Colorado Medicaid\\PreStaged\\CleanAge13.dta FALSE
##                                                                         mode
## E:\\Share\\DataRepository\\Colorado Medicaid\\PreStaged\\CleanAge13.dta  666
##                                                                                       mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\PreStaged\\CleanAge13.dta 2015-07-02 16:59:12
##                                                                                       ctime
## E:\\Share\\DataRepository\\Colorado Medicaid\\PreStaged\\CleanAge13.dta 2015-07-02 16:12:39
##                                                                                       atime
## E:\\Share\\DataRepository\\Colorado Medicaid\\PreStaged\\CleanAge13.dta 2015-07-02 16:12:39
##                                                                         exe
## E:\\Share\\DataRepository\\Colorado Medicaid\\PreStaged\\CleanAge13.dta  no
correctedAges <- read.dta13(f)
correctedAges <- data.table(correctedAges)
correctedAges <- correctedAges[, CLNT_ID := sprintf("%07d", clnt_id)]
correctedAges <- correctedAges[, clnt_id := NULL]
setkey(correctedAges, snapshot_period_id)

Merge Rich’s corrected age to the working data table.

SnapshotPeriodDefinition <- read.sas7bdat(sprintf("%s\\%s\\%s", pathData, "PreStaged", "SnapshotPeriodDefinition.sas7bdat"))
SnapshotPeriodDefinition <- data.table(SnapshotPeriodDefinition)
setnames(SnapshotPeriodDefinition, names(SnapshotPeriodDefinition), tolower(names(SnapshotPeriodDefinition)))
SnapshotPeriodDefinition <- SnapshotPeriodDefinition[, list(snapshot_period_id, snapshot_beg_dt)]
SnapshotPeriodDefinition <- SnapshotPeriodDefinition[, dateCoverageBegin := as.Date(as.POSIXlt(snapshot_beg_dt, origin="1960-01-01", tz="GMT"))]
SnapshotPeriodDefinition <- SnapshotPeriodDefinition[, snapshot_beg_dt := NULL]
setkey(SnapshotPeriodDefinition, snapshot_period_id)
if (identical(key(correctedAges), key(SnapshotPeriodDefinition))) {
  correctedAges <- merge(correctedAges, SnapshotPeriodDefinition)
} else {
  warning("Key mismatch")
}
setkey(correctedAges, CLNT_ID, dateCoverageBegin)
setkeyv(D0, key(correctedAges))
D0 <- merge(D0, correctedAges)

Make sure all rows got a corrected age merged on. If you see a warning message, then not all rows got an age value.

if (is.null(nrow(D0[is.na(clnt_age), clnt_age]))) {
  message("All is well")
} else {
  warning(sprintf("%s out of %s (%0.4f%%) rows did not get a corrected age merged on.",
                format(nrow(D0[is.na(clnt_age), clnt_age]), big.mark=","),
                format(nrow(D0), big.mark=","),
                100 * nrow(D0[is.na(clnt_age), clnt_age]) / nrow(D0)))
}
## All is well

Check age variables

  • age is the original age variable from the client snapshot
  • clnt_age is the age variable from Rich’s corrected data file
cor(D0[, list(age, clnt_age)])
##                age  clnt_age
## age      1.0000000 0.9988408
## clnt_age 0.9988408 1.0000000
message(sprintf("%s out of %s (%0.4f%%) age values do not match.",
                format(sum(D0[, age != clnt_age]), big.mark=","),
                format(nrow(D0), big.mark=","),
                100 * sum(D0[, age != clnt_age]) / nrow(D0)))
## 3,046 out of 6,900,245 (0.0441%) age values do not match.
D0[age != clnt_age, .N, list(diffAgeValues = age - clnt_age)][order(diffAgeValues)]
##     diffAgeValues    N
##  1:           -46    4
##  2:           -40    2
##  3:           -36    1
##  4:           -35    2
##  5:           -30    3
##  6:           -27    1
##  7:           -25    1
##  8:           -24    2
##  9:           -20   25
## 10:           -18   13
## 11:           -17    3
## 12:           -16   15
## 13:           -15   12
## 14:           -14    7
## 15:           -13   13
## 16:           -12   10
## 17:           -11    5
## 18:           -10  113
## 19:            -9   13
## 20:            -8   11
## 21:            -7   12
## 22:            -6    4
## 23:            -5   37
## 24:            -4  113
## 25:            -3  161
## 26:            -2  313
## 27:            -1 1038
## 28:             1  616
## 29:             2  149
## 30:             3   58
## 31:             4    4
## 32:             5   27
## 33:             6   43
## 34:             7   15
## 35:             8   22
## 36:             9   11
## 37:            10   52
## 38:            13    8
## 39:            14    7
## 40:            15    3
## 41:            17    1
## 42:            18    4
## 43:            22    1
## 44:            23    5
## 45:            24    6
## 46:            30    5
## 47:            33    1
## 48:            37    1
## 49:            49    1
## 50:            52    8
## 51:            78   21
## 52:            79   18
## 53:            80    2
## 54:           100    1
## 55:           207    1
## 56:           228    1
## 57:           235    2
## 58:           243    4
## 59:           244   12
## 60:           246    1
## 61:           248    1
##     diffAgeValues    N

Remove original age variable and snapshot_period_id. Rename Rich’s corrected age to age.

D0 <- D0[, age := NULL]
D0 <- D0[, snapshot_period_id := NULL]
setnames(D0, "clnt_age", "age")

Fix age indicators.

D0 <- D0[,
         `:=` (isChildBearingAge = gender == "F" & (13 <= age & age <= 66),
               isAgeOver64 = 64 < age)]

5.3 Create member months lookup

Borrows heavily from Stephanie’s APAC and Oregon Medicaid staging code, 050CreateOregonMemberMonthsLookupAPACmed.Rmd and 051CreateContinuousEnrollmentLookupAPACmed.Rmd.

Convert the Oregon eligibility data to member months to mimick the format of Colorado’s data. The output file is called Member_Months_LU.Rdata.

Note: Some HEDIS measures require that members be enrolled with a specific type of coverage during the anchor date (last member month of the measurement year). The recipient data used for the rest of this project is based on physical health eligibility only. That’s okay because members can’t be enrolled in one type of coverage without being enrolled in all three types (physical health, mental health, drug). See chunk in SCRAP CODE at the end of this program where I verify that is the case. Need to make sure this is also true for Colorado data.

5.3.1 Assumptions

Our default method is to count as member months any month during which the member is enrolled on a specific fixed date that month. This is per Stephanie’s email with a former co-worker, Cindi. Rich is verifying that Colorado is using a similar method to determine their member months, as well as the fixed date they use. We use the 15th of the month as our default, because it’s easier to program.

From: Cindi McElhaney [mailto:Cindi.McElhaney@q-corp.org]   
Sent: Friday, February 28, 2014 8:55 AM   
To: Stephanie Renfro  
Subject: RE: Medicaid enrollment question  

Hi Steph,  

Most of the HEDIS measures allow for one 45 day gap in coverage for Medicaid
members. The easiest way to do this is to count the number of days a  person
is enrolled during your report period, and then exclude anyone who has fewer
days than your threshold. For example, if you want continuous enrollment for a
year, you would exclude anyone who was enrolled less than 320 days (365-45).
You could potentially exclude people who had multiple short gaps (say nine
5-day gaps instead of one 45 day gap), but that's highly unlikely to happen.

However, it doesn't appear CO did that because there is no accounting for a
partial month. My guess is they gave you member months. The standard method is
to picked a fixed date for each month (say the 15th or the 31st), and then
counted the member as enrolled if they were active on that date. It's not
HEDIS protocol, but it would work to get your OR file into the same format as
CO.

I hope that helps. Let me know if you have any questions,   
Cindi  

From: Stephanie Renfro [renfrst@ohsu.edu]   
Sent: Thursday, February 27, 2014 9:32 AM   
To: Cindi McElhaney   
Subject: Medicaid enrollment question  

Hey Cindi,  

Can I bug you? I have two Medicaid data sets - one from Oregon and one from
Colorado. Oregon's enrollment is recorded as specific start and end dates, for
example:

MEMBER_ID  dateCoverageBegin  dateCoverageEnd   
123 1/1/10  3/10/10   
123 5/1/10  8/31/10   
456 5/3/10  7/31/10   

Colorado only provides enrollment by month and year. I know HEDIS measures
have instructions on how to determine continuous enrollment (and gaps) for
Medicaid members when enrollment is only verified on a monthly basis. I want
to convert the Oregon enrollment periods to the same format as Colorado's data
so we can use the same method to determine continuous enrollment for both data
sets. In other words, I want to make the table above look like this:

MEMBER_ID MM_MONTH  MM_YEAR   
123 1 2010    
123 2 2010    
123 3 2010    
123 5 2010    
123 6 2010    
123 7 2010    
123 8 2010    
456 5 2010    
456 6 2010    
456 7 2010    

I don't know if the highlighted rows should be included, since the member was
only enrolled for part of the month. I haven't been able to find out from
Colorado how their monthly eligibility determinations work, and I've asked Kim
Rose and Steve Broich for tips, but they gave me info on determining member
months (which isn't what I'm doing here).

Do you know how it works to determine Medicaid enrollment on a monthly basis?
Not sure if there's a standard protocol.

Thanks,  
Steph

Strip down to memberID and enrollment month.

D <- D0[, list(memberID, dateCoverageBegin)]

Add month fields; value is TRUE if the month matches the enrollment start date. Add year field, populated based on enrollment start date.

D <- D[,
       `:=` (Jan = format(dateCoverageBegin, "%m") == "01",
             Feb = format(dateCoverageBegin, "%m") == "02",
             Mar = format(dateCoverageBegin, "%m") == "03",
             Apr = format(dateCoverageBegin, "%m") == "04",
             May = format(dateCoverageBegin, "%m") == "05",
             Jun = format(dateCoverageBegin, "%m") == "06",
             Jul = format(dateCoverageBegin, "%m") == "07",
             Aug = format(dateCoverageBegin, "%m") == "08",
             Sep = format(dateCoverageBegin, "%m") == "09",
             Oct = format(dateCoverageBegin, "%m") == "10",
             Nov = format(dateCoverageBegin, "%m") == "11",
             Dec = format(dateCoverageBegin, "%m") == "12",
             year = format(dateCoverageBegin, "%Y"))]

Create mm table that condenses the enrollment data to a single row per member and year. Note, the original enrollment start dates are dropped at this step. Now, all we have is member months.

mm <- D[,
        list(Jan = max(Jan),
             Feb = max(Feb),
             Mar = max(Mar),
             Apr = max(Apr),
             May = max(May),
             Jun = max(Jun),
             Jul = max(Jul),
             Aug = max(Aug),
             Sep = max(Sep),
             Oct = max(Oct),
             Nov = max(Nov),
             Dec = max(Dec)),
        list(memberID, year)]

Convert the data into a format with a single row per member. “Wide” datasets take up less memory than “long” datasets.

  • First, separate the data into separate dataframes for each year
    • We only have enrollment records as far back as 2009
    • But create data frames as far back as 2006
    • These early “enrollment” records will serve as non-TRUE “filler” for longer look-backs
  • Then, add the year to each of the month variable names
  • Finally, join the dataframes into a single dataframe with one row per member
  • The join will produce NAs for members that were not enrolled during a given year.
    • Convert these to 0s
years <- c(2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014)
for(i in 1:length(years)) {
  assign(paste("mm", years[i], sep=""), mm[year == years[i], ])
}
Replace_Month_Names <- function(data, year) {
  months <- c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")
  for(i in 1:length(months)) {
    setnames(data, old=months[i], new=paste(months[i], year, sep="_"))
  }
  data <- data[, `:=`(year = NULL)]
  return(data)
}
mm2006 <- Replace_Month_Names(mm2006, 2006)
mm2007 <- Replace_Month_Names(mm2007, 2007)
mm2008 <- Replace_Month_Names(mm2008, 2008)
mm2009 <- Replace_Month_Names(mm2009, 2009)
mm2010 <- Replace_Month_Names(mm2010, 2010)
mm2011 <- Replace_Month_Names(mm2011, 2011)
mm2012 <- Replace_Month_Names(mm2012, 2012)
mm2013 <- Replace_Month_Names(mm2013, 2013)
mm2014 <- Replace_Month_Names(mm2014, 2014)
Member_Months_LU <- merge(mm2006, mm2007, by="memberID", all=TRUE)
Member_Months_LU <- merge(Member_Months_LU, mm2008, by="memberID", all=TRUE)
Member_Months_LU <- merge(Member_Months_LU, mm2009, by="memberID", all=TRUE)
Member_Months_LU <- merge(Member_Months_LU, mm2010, by="memberID", all=TRUE)
Member_Months_LU <- merge(Member_Months_LU, mm2011, by="memberID", all=TRUE)
Member_Months_LU <- merge(Member_Months_LU, mm2012, by="memberID", all=TRUE)
Member_Months_LU <- merge(Member_Months_LU, mm2013, by="memberID", all=TRUE)
Member_Months_LU <- merge(Member_Months_LU, mm2014, by="memberID", all=TRUE)
Member_Months_LU[is.na(Member_Months_LU)] <- 0

Save the dataset as Member_Months_LU.RData.

f <- sprintf("%s\\%s", pathStaged, "Member_Months_LU.RData")
metadata <- makeMetadata("makeClientSnapshot.Rmd")
save(metadata, Member_Months_LU, file=f)
file.info(f)[c("size", "mtime")]
##                                                                                 size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\Member_Months_LU.RData 4624609
##                                                                                            mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\Member_Months_LU.RData 2015-07-17 16:49:27
rm(mm, mm2006, mm2007, mm2008, mm2009, mm2010, mm2011, mm2012, mm2013, mm2014)

5.4 Create continuous enrollment lookup

This program determines which members meet HEDIS continuous enrollment criteria, for measures that use the same continuous enrollment periods for the entire measure population. For example, Cervical Cancer Screenings requires members to be continuously enrolled during the measurement year and the year prior to the measurement year. On the contrary, Well-Child Visits During the First 15 Months of Life requires members to be continuously enrolled from age 31 days through 15 months; this period changes for each member.

5.4.1 Medicaid Enrollment & Allowable Gaps

This program is written for Medicaid members whose enrollment is verified on a monthly basis. The HEDIS instructions say:

To determine continuous enrollment for a Medicaid beneficiary for whom enrollment is verified monthly, the member may not have more than a 1-month gap in coverage (i.e., a member whose coverage lapses for 2 months [60 days] is not considered continuously enrolled).

For continuous enrollment periods of 12 months, up to one gap (missing member month) is permitted. For continuous enrollment periods more than 12 months, up to one gap is permitted per year. Some measures (e.g. Breast Cancer SCreenings) require additional segments of continuous enrollment, in increments less than 12 months. See the following email from NCQA confirming that no gaps are allowed during these extra segements.

From: PCS [donotreply@ncqa.org]   
Sent: Wednesday, March 05, 2014 10:14 AM    
To: Stephanie Renfro    
Subject: NCQA PCS Response to Case #00012283    

Customer's Name: Stephanie Renfro     

You asked the following question:   
Re: Continuous Enrollment Criteria    
Hello, For the Breast Cancer Screening measure, eligible members are required
to be continuously enrolled "October 1 two years prior to the measurement year
through December 31 of the measurement year," with "no more than one gap in
enrollment of up to 45 days during each year of continuous enrollment." My
question is, can there be a gap during the Oct 1 - Dec 31 period two years
prior to the measurement year? For example, if the measurement year is Jan 1 -
Dec 31, 2014, the member must be continuously enrolled between Oct 1, 2012 -
Dec 31, 2014. The member may have up to one gap of up to 45 days in 2013 and
2014, but what about the two months in 2012? Are gaps allowed? Thanks,  
Stephanie

NCQA's response:    
No gaps in enrollment are allowed from October 1 two years prior to the
measurement year through December 31 two years prior to the measurement year.
This clarification is included in the HEDIS 2014 Volume 2 Technical Update,
which is available on our website at
[http://www.ncqa.org/HEDISQualityMeasurement/HEDISMeasures/HEDIS2014.aspx](http://www.ncqa.org/HEDISQualityMeasurement/HEDISMeasures/HEDIS2014.aspx).
Please keep in mind that for HEDIS 2014, the measurement year is the 2013
calendar year (January 1, 2013 - December 31, 2013). For HEDIS 2014 reporting
(the 2013 measurement year), the continuous enrollment period and numerator
timeframe for the BCS measure is October 1, 2011 (i.e., October 1 two years
prior to the measurement year) through December 31, 2013. Therefore, no gaps
in enrollment would be allowed October 1, 2011 to December 31, 2011.

5.4.2 Output

The program receives an enrollment file in member months format and adds columns to it in the format Cont_En_YYYYQ#_XXm, where

  • YYYY is the year corresponding with the last quarter of the measurement period
  • Q# is the quarter corresponding with the last quarter of the measurement period
  • XX is the number of months included in the continuous enrollment period, i.e.

    • A 12 month period looks for continuous enrollment during the measurement year only, with up to one gap (missing member month)

    • A 24 month period looks for continuous enrollment during the measurement year and the year prior, with up to one gap of enrollment during each year

    • A 27 month period looks for continuous enrollment during the measurement year, the year prior to the measurement year, and the three months before that, with up to one gap of enrollment during each of the latter 12-month periods, and no gaps during the first three months

    • A 36 month period looks for continuous enrollment during the measurement year and two years prior to the measurement year, with up to one gap of enrollment during each year

For example: The field Cont_En_2011Q4_15m identifies continuous enrollment for the 15 month period ending with the 4th quarter of 2011, i.e. Oct 1, 2010 - Dec 31, 2011. The member may have one gap in enrollment between Jan 1,2011 - Dec 31, 2011, but they must be enrolled between Oct 1, 2010 - Dec 31, 2010.

5.4.3 Assumptions

This program assumes that all measures have continuous enrollment periods that are less than 3 years. If a measure is added with a continuous enrollment priod of 3 or more years, the program will have to be modified.

5.4.4 Program

Load the member months table and call it Cont_En_LU. Remove Member_Months_LU.

file.info(f)[c("size", "mtime")]
##                                                                                 size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\Member_Months_LU.RData 4624609
##                                                                                            mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\Member_Months_LU.RData 2015-07-17 16:49:27
if (!exists("Member_Months_LU")) load(f, verbose=TRUE)
Cont_En_LU <- Member_Months_LU
rm(Member_Months_LU)

Define Create_Cont_En function that adds a member-level indicator for members meeting the given continuous enrollment criteria (user input).

Create_Cont_En <- function(data,year_end,quarter_end,length,gap) {
  data$x <- NA
  if (quarter_end=="Q1") {month_end <- "Mar"} else
  if (quarter_end=="Q2") {month_end <- "Jun"} else
  if (quarter_end=="Q3") {month_end <- "Sep"} else
  if (quarter_end=="Q4") {month_end <- "Dec"}
  last <- paste(month_end,year_end,sep="_")
  last_pos <- which(colnames(data)==last)
  if (length<12) {
    end <- last_pos
    start <- end-(length-1)
    data$x <- rowSums(data[,start:end,with=F]) >= length
    data$x <- data$x + 0
  }
  if (length>=12) {
    n <- floor(length/12)
    end <- last_pos
    for(z in 1:n) {
      start <- end-(12-1)
      assign(paste("interval_",z,sep=""), rowSums(data[,start:end,with=F]) >= (12-gap))
      end <- end-12
      z <- z+1
    }
    extra <- length-n*12
    if(!extra==0) {
      assign("interval_extra", rowSums(data[,(end-extra):(end-1),with=F]) >= (extra))
    
      if(n==1) {data$x <- interval_1*interval_extra}
      if(n==2) {data$x <- interval_1*interval_2*interval_extra}
      if(n==3) {data$x <- interval_1*interval_2*interval_3*interval_extra}
      }
    if(extra==0) {
      if(n==1) {data$x <- interval_1+0}
      if(n==2) {data$x <- interval_1*interval_2}
      if(n==3) {data$x <- interval_1*interval_2*interval_3}
      }
  }
  setnames(data, old="x", new=paste("Cont_En_",year_end,quarter_end,"_",length,"m",sep=""))
  return(data)
}

Apply function for all the years, quarters, and continuous enrollment period lengths of interest.

years <- c("2009", "2010", "2011", "2012", "2013", "2014")
quarters <- c("Q1", "Q2", "Q3", "Q4")
lengths <- c(3, 12, 24, 27, 36)
for (i in 1:length(years)) {
  for (j in 1:length(quarters)) {
    for (k in 1:length(lengths)) {
      Cont_En_LU <- Create_Cont_En(Cont_En_LU, years[i], quarters[j], lengths[k], 1)
    }
  }
}

Remove member months fields, leaving only member IDs and continuous enrollment fields.

names(Cont_En_LU)
##   [1] "memberID"           "Jan_2006"           "Feb_2006"          
##   [4] "Mar_2006"           "Apr_2006"           "May_2006"          
##   [7] "Jun_2006"           "Jul_2006"           "Aug_2006"          
##  [10] "Sep_2006"           "Oct_2006"           "Nov_2006"          
##  [13] "Dec_2006"           "Jan_2007"           "Feb_2007"          
##  [16] "Mar_2007"           "Apr_2007"           "May_2007"          
##  [19] "Jun_2007"           "Jul_2007"           "Aug_2007"          
##  [22] "Sep_2007"           "Oct_2007"           "Nov_2007"          
##  [25] "Dec_2007"           "Jan_2008"           "Feb_2008"          
##  [28] "Mar_2008"           "Apr_2008"           "May_2008"          
##  [31] "Jun_2008"           "Jul_2008"           "Aug_2008"          
##  [34] "Sep_2008"           "Oct_2008"           "Nov_2008"          
##  [37] "Dec_2008"           "Jan_2009"           "Feb_2009"          
##  [40] "Mar_2009"           "Apr_2009"           "May_2009"          
##  [43] "Jun_2009"           "Jul_2009"           "Aug_2009"          
##  [46] "Sep_2009"           "Oct_2009"           "Nov_2009"          
##  [49] "Dec_2009"           "Jan_2010"           "Feb_2010"          
##  [52] "Mar_2010"           "Apr_2010"           "May_2010"          
##  [55] "Jun_2010"           "Jul_2010"           "Aug_2010"          
##  [58] "Sep_2010"           "Oct_2010"           "Nov_2010"          
##  [61] "Dec_2010"           "Jan_2011"           "Feb_2011"          
##  [64] "Mar_2011"           "Apr_2011"           "May_2011"          
##  [67] "Jun_2011"           "Jul_2011"           "Aug_2011"          
##  [70] "Sep_2011"           "Oct_2011"           "Nov_2011"          
##  [73] "Dec_2011"           "Jan_2012"           "Feb_2012"          
##  [76] "Mar_2012"           "Apr_2012"           "May_2012"          
##  [79] "Jun_2012"           "Jul_2012"           "Aug_2012"          
##  [82] "Sep_2012"           "Oct_2012"           "Nov_2012"          
##  [85] "Dec_2012"           "Jan_2013"           "Feb_2013"          
##  [88] "Mar_2013"           "Apr_2013"           "May_2013"          
##  [91] "Jun_2013"           "Jul_2013"           "Aug_2013"          
##  [94] "Sep_2013"           "Oct_2013"           "Nov_2013"          
##  [97] "Dec_2013"           "Jan_2014"           "Feb_2014"          
## [100] "Mar_2014"           "Apr_2014"           "May_2014"          
## [103] "Jun_2014"           "Jul_2014"           "Aug_2014"          
## [106] "Sep_2014"           "Oct_2014"           "Nov_2014"          
## [109] "Dec_2014"           "Cont_En_2009Q1_3m"  "Cont_En_2009Q1_12m"
## [112] "Cont_En_2009Q1_24m" "Cont_En_2009Q1_27m" "Cont_En_2009Q1_36m"
## [115] "Cont_En_2009Q2_3m"  "Cont_En_2009Q2_12m" "Cont_En_2009Q2_24m"
## [118] "Cont_En_2009Q2_27m" "Cont_En_2009Q2_36m" "Cont_En_2009Q3_3m" 
## [121] "Cont_En_2009Q3_12m" "Cont_En_2009Q3_24m" "Cont_En_2009Q3_27m"
## [124] "Cont_En_2009Q3_36m" "Cont_En_2009Q4_3m"  "Cont_En_2009Q4_12m"
## [127] "Cont_En_2009Q4_24m" "Cont_En_2009Q4_27m" "Cont_En_2009Q4_36m"
## [130] "Cont_En_2010Q1_3m"  "Cont_En_2010Q1_12m" "Cont_En_2010Q1_24m"
## [133] "Cont_En_2010Q1_27m" "Cont_En_2010Q1_36m" "Cont_En_2010Q2_3m" 
## [136] "Cont_En_2010Q2_12m" "Cont_En_2010Q2_24m" "Cont_En_2010Q2_27m"
## [139] "Cont_En_2010Q2_36m" "Cont_En_2010Q3_3m"  "Cont_En_2010Q3_12m"
## [142] "Cont_En_2010Q3_24m" "Cont_En_2010Q3_27m" "Cont_En_2010Q3_36m"
## [145] "Cont_En_2010Q4_3m"  "Cont_En_2010Q4_12m" "Cont_En_2010Q4_24m"
## [148] "Cont_En_2010Q4_27m" "Cont_En_2010Q4_36m" "Cont_En_2011Q1_3m" 
## [151] "Cont_En_2011Q1_12m" "Cont_En_2011Q1_24m" "Cont_En_2011Q1_27m"
## [154] "Cont_En_2011Q1_36m" "Cont_En_2011Q2_3m"  "Cont_En_2011Q2_12m"
## [157] "Cont_En_2011Q2_24m" "Cont_En_2011Q2_27m" "Cont_En_2011Q2_36m"
## [160] "Cont_En_2011Q3_3m"  "Cont_En_2011Q3_12m" "Cont_En_2011Q3_24m"
## [163] "Cont_En_2011Q3_27m" "Cont_En_2011Q3_36m" "Cont_En_2011Q4_3m" 
## [166] "Cont_En_2011Q4_12m" "Cont_En_2011Q4_24m" "Cont_En_2011Q4_27m"
## [169] "Cont_En_2011Q4_36m" "Cont_En_2012Q1_3m"  "Cont_En_2012Q1_12m"
## [172] "Cont_En_2012Q1_24m" "Cont_En_2012Q1_27m" "Cont_En_2012Q1_36m"
## [175] "Cont_En_2012Q2_3m"  "Cont_En_2012Q2_12m" "Cont_En_2012Q2_24m"
## [178] "Cont_En_2012Q2_27m" "Cont_En_2012Q2_36m" "Cont_En_2012Q3_3m" 
## [181] "Cont_En_2012Q3_12m" "Cont_En_2012Q3_24m" "Cont_En_2012Q3_27m"
## [184] "Cont_En_2012Q3_36m" "Cont_En_2012Q4_3m"  "Cont_En_2012Q4_12m"
## [187] "Cont_En_2012Q4_24m" "Cont_En_2012Q4_27m" "Cont_En_2012Q4_36m"
## [190] "Cont_En_2013Q1_3m"  "Cont_En_2013Q1_12m" "Cont_En_2013Q1_24m"
## [193] "Cont_En_2013Q1_27m" "Cont_En_2013Q1_36m" "Cont_En_2013Q2_3m" 
## [196] "Cont_En_2013Q2_12m" "Cont_En_2013Q2_24m" "Cont_En_2013Q2_27m"
## [199] "Cont_En_2013Q2_36m" "Cont_En_2013Q3_3m"  "Cont_En_2013Q3_12m"
## [202] "Cont_En_2013Q3_24m" "Cont_En_2013Q3_27m" "Cont_En_2013Q3_36m"
## [205] "Cont_En_2013Q4_3m"  "Cont_En_2013Q4_12m" "Cont_En_2013Q4_24m"
## [208] "Cont_En_2013Q4_27m" "Cont_En_2013Q4_36m" "Cont_En_2014Q1_3m" 
## [211] "Cont_En_2014Q1_12m" "Cont_En_2014Q1_24m" "Cont_En_2014Q1_27m"
## [214] "Cont_En_2014Q1_36m" "Cont_En_2014Q2_3m"  "Cont_En_2014Q2_12m"
## [217] "Cont_En_2014Q2_24m" "Cont_En_2014Q2_27m" "Cont_En_2014Q2_36m"
## [220] "Cont_En_2014Q3_3m"  "Cont_En_2014Q3_12m" "Cont_En_2014Q3_24m"
## [223] "Cont_En_2014Q3_27m" "Cont_En_2014Q3_36m" "Cont_En_2014Q4_3m" 
## [226] "Cont_En_2014Q4_12m" "Cont_En_2014Q4_24m" "Cont_En_2014Q4_27m"
## [229] "Cont_En_2014Q4_36m"
months <- c("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec")
Cont_En_LU <- subset(Cont_En_LU,select=c(!substr(names(Cont_En_LU),1,3) %in% months))
names(Cont_En_LU)
##   [1] "memberID"           "Cont_En_2009Q1_3m"  "Cont_En_2009Q1_12m"
##   [4] "Cont_En_2009Q1_24m" "Cont_En_2009Q1_27m" "Cont_En_2009Q1_36m"
##   [7] "Cont_En_2009Q2_3m"  "Cont_En_2009Q2_12m" "Cont_En_2009Q2_24m"
##  [10] "Cont_En_2009Q2_27m" "Cont_En_2009Q2_36m" "Cont_En_2009Q3_3m" 
##  [13] "Cont_En_2009Q3_12m" "Cont_En_2009Q3_24m" "Cont_En_2009Q3_27m"
##  [16] "Cont_En_2009Q3_36m" "Cont_En_2009Q4_3m"  "Cont_En_2009Q4_12m"
##  [19] "Cont_En_2009Q4_24m" "Cont_En_2009Q4_27m" "Cont_En_2009Q4_36m"
##  [22] "Cont_En_2010Q1_3m"  "Cont_En_2010Q1_12m" "Cont_En_2010Q1_24m"
##  [25] "Cont_En_2010Q1_27m" "Cont_En_2010Q1_36m" "Cont_En_2010Q2_3m" 
##  [28] "Cont_En_2010Q2_12m" "Cont_En_2010Q2_24m" "Cont_En_2010Q2_27m"
##  [31] "Cont_En_2010Q2_36m" "Cont_En_2010Q3_3m"  "Cont_En_2010Q3_12m"
##  [34] "Cont_En_2010Q3_24m" "Cont_En_2010Q3_27m" "Cont_En_2010Q3_36m"
##  [37] "Cont_En_2010Q4_3m"  "Cont_En_2010Q4_12m" "Cont_En_2010Q4_24m"
##  [40] "Cont_En_2010Q4_27m" "Cont_En_2010Q4_36m" "Cont_En_2011Q1_3m" 
##  [43] "Cont_En_2011Q1_12m" "Cont_En_2011Q1_24m" "Cont_En_2011Q1_27m"
##  [46] "Cont_En_2011Q1_36m" "Cont_En_2011Q2_3m"  "Cont_En_2011Q2_12m"
##  [49] "Cont_En_2011Q2_24m" "Cont_En_2011Q2_27m" "Cont_En_2011Q2_36m"
##  [52] "Cont_En_2011Q3_3m"  "Cont_En_2011Q3_12m" "Cont_En_2011Q3_24m"
##  [55] "Cont_En_2011Q3_27m" "Cont_En_2011Q3_36m" "Cont_En_2011Q4_3m" 
##  [58] "Cont_En_2011Q4_12m" "Cont_En_2011Q4_24m" "Cont_En_2011Q4_27m"
##  [61] "Cont_En_2011Q4_36m" "Cont_En_2012Q1_3m"  "Cont_En_2012Q1_12m"
##  [64] "Cont_En_2012Q1_24m" "Cont_En_2012Q1_27m" "Cont_En_2012Q1_36m"
##  [67] "Cont_En_2012Q2_3m"  "Cont_En_2012Q2_12m" "Cont_En_2012Q2_24m"
##  [70] "Cont_En_2012Q2_27m" "Cont_En_2012Q2_36m" "Cont_En_2012Q3_3m" 
##  [73] "Cont_En_2012Q3_12m" "Cont_En_2012Q3_24m" "Cont_En_2012Q3_27m"
##  [76] "Cont_En_2012Q3_36m" "Cont_En_2012Q4_3m"  "Cont_En_2012Q4_12m"
##  [79] "Cont_En_2012Q4_24m" "Cont_En_2012Q4_27m" "Cont_En_2012Q4_36m"
##  [82] "Cont_En_2013Q1_3m"  "Cont_En_2013Q1_12m" "Cont_En_2013Q1_24m"
##  [85] "Cont_En_2013Q1_27m" "Cont_En_2013Q1_36m" "Cont_En_2013Q2_3m" 
##  [88] "Cont_En_2013Q2_12m" "Cont_En_2013Q2_24m" "Cont_En_2013Q2_27m"
##  [91] "Cont_En_2013Q2_36m" "Cont_En_2013Q3_3m"  "Cont_En_2013Q3_12m"
##  [94] "Cont_En_2013Q3_24m" "Cont_En_2013Q3_27m" "Cont_En_2013Q3_36m"
##  [97] "Cont_En_2013Q4_3m"  "Cont_En_2013Q4_12m" "Cont_En_2013Q4_24m"
## [100] "Cont_En_2013Q4_27m" "Cont_En_2013Q4_36m" "Cont_En_2014Q1_3m" 
## [103] "Cont_En_2014Q1_12m" "Cont_En_2014Q1_24m" "Cont_En_2014Q1_27m"
## [106] "Cont_En_2014Q1_36m" "Cont_En_2014Q2_3m"  "Cont_En_2014Q2_12m"
## [109] "Cont_En_2014Q2_24m" "Cont_En_2014Q2_27m" "Cont_En_2014Q2_36m"
## [112] "Cont_En_2014Q3_3m"  "Cont_En_2014Q3_12m" "Cont_En_2014Q3_24m"
## [115] "Cont_En_2014Q3_27m" "Cont_En_2014Q3_36m" "Cont_En_2014Q4_3m" 
## [118] "Cont_En_2014Q4_12m" "Cont_En_2014Q4_24m" "Cont_En_2014Q4_27m"
## [121] "Cont_En_2014Q4_36m"

Sort continuous enrollment lookup table by member ID. Display the first few rows.

#setkey(Cont_En_LU, memberID)
Cont_En_LU <- Cont_En_LU[order(Cont_En_LU$memberID),]

Save continuous enrollment lookup table to drive as Cont_En_LU.RData. Clean up.

f <- sprintf("%s\\%s", pathStaged, "Cont_En_LU.RData")
metadata <- makeMetadata("makeClientSnapshot.Rmd")
save(metadata, Cont_En_LU, file=f)
file.info(f)[c("size", "mtime")]
##                                                                           size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\Cont_En_LU.RData 4685959
##                                                                                      mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\Cont_En_LU.RData 2015-07-17 16:51:49
# str(Cont_En_LU)
rm(Cont_En_LU)
gc()
##             used   (Mb) gc trigger    (Mb)   max used    (Mb)
## Ncells   3219058  172.0    5241317   280.0    5241317   280.0
## Vcells 603699152 4605.9 1771272994 13513.8 1771270278 13513.8

5.5 Create member detail

Borrows heavily from Stephanie’s APAC and Oregon Medicaid staging code, 090CreateMemberDetailFileAPAC.Rmd.

Define function Create_mem_detail that creates a mem_detail recipient file with member characteristics of interest for each study period. A new variable, yearEnding, corresponds to the last day of the rolling 12-month study periods. yearEnding can take on values of the following format:

  • YYYY-03-31
  • YYYY-06-30
  • YYYY-09-30
  • YYYY-12-31

The member data for each study period is consistent with the last observed enrollment segment for that period. At most one observation is included per yearEnding value per member.

Create_mem_detail <- function(data, study_year) {
  # First, create four dataframes, one for each yearEnding date, that include
  # enrollment segments overlapping with that yearEnding date.
  # Note, this code differs slightly from the Medicaid data processing version
  # b/c APAC data has member months, not start/end dates.
  data_03_31 <- data[between(dateCoverageBegin, 
                             sprintf("%d-04-01", study_year-1), 
                             sprintf("%d-03-31", study_year  ))]
  data_03_31 <- data_03_31[, yearEnding := as.Date(sprintf("%d-03-31", study_year))]
  data_06_30 <- data[between(dateCoverageBegin, 
                             sprintf("%d-07-01", study_year-1), 
                             sprintf("%d-06-30", study_year  ))]
  data_06_30 <- data_06_30[, yearEnding := as.Date(sprintf("%d-06-30", study_year))]
  data_09_30 <- data[between(dateCoverageBegin, 
                             sprintf("%d-10-01", study_year-1), 
                             sprintf("%d-09-30", study_year  ))]
  data_09_30 <- data_09_30[, yearEnding := as.Date(sprintf("%d-09-30", study_year))]
  data_12_31 <- data[between(dateCoverageBegin, 
                             sprintf("%d-01-01", study_year-1), 
                             sprintf("%d-12-31", study_year  ))]
  data_12_31 <- data_12_31[, yearEnding := as.Date(sprintf("%d-12-31", study_year))]
  # Stack the four dataframes
  output <- rbind(data_03_31, data_06_30, data_09_30, data_12_31)
  # Sort the new dataframe in descending order by member ID, yearEnding, and
  # enrollment segment end date
  output <- output[order(memberID, yearEnding, dateCoverageBegin, decreasing=TRUE),]
  # Get rid of all but the first observation for each member ID/yearEnding
  # combination
  output <- output[!duplicated(output[,list(memberID,yearEnding)], by=NULL),]
  # Re-sort the new dataframe in ascending order to make it more viewer-friendly
  output <- output[order(memberID, yearEnding, dateCoverageBegin, decreasing=FALSE),]
  if(i==1) {mem_detail_Colorado <- output}
  if(!i==1) {mem_detail_Colorado <- rbind(mem_detail_Colorado, output)}
  return(mem_detail_Colorado)
}

Run the Create_mem_detail function for each study year to create mem_detail_Colorado.

study_years <- c(2010, 2011, 2012, 2013, 2014)
for(i in 1:length(study_years)) {
  mem_detail_Colorado <- Create_mem_detail(D0, study_years[i])
}

Check that one observation is included per yearEnding value per member. Only show a warning if the check fails.

test <- mem_detail_Colorado[, list(memberID, yearEnding)]
setkey(test, memberID, yearEnding)
n1 <- nrow(test)
n2 <- nrow(unique(test))
if (!(identical(n1, n2))) {
  warning(sprintf("%s\n%s\n%d %s\n%d %s", 
                  "Function `Create_mem_detail` returned an unexpected result",
                  "(memberID, yearEnding) combinations are not unique",
                  n1,
                  "rows in data table",
                  n2,
                  "unique (memberID, yearEnding) combinations"))
}
rm(test, n1, n2)

Drop dateCoverageBegin because the new yearEnding variable is now serving as our time reference.

mem_detail_Colorado <- mem_detail_Colorado[, `:=` (dateCoverageBegin = NULL)]

The is where clients age 65+ are excluded. However, we are only including Standard and Expansion populations. Dual eligibles are excluded. There should not be any clients age 65+.

Check and decide what to do with these clients.

test <- mem_detail_Colorado[, list(memberID, yearEnding, isAgeOver64)]
setkey(test, memberID, yearEnding)
T <- test[, .N, isAgeOver64]
test[, .N, isAgeOver64][, list(isAgeOver64, N, prop = N / sum(N))]
##    isAgeOver64       N         prop
## 1:       FALSE 2840863 9.999402e-01
## 2:        TRUE     170 5.983739e-05
if (T[isAgeOver64 == TRUE, N] > 0) {
  warning(sprintf("%s **%d (%.2f%%)** %s",
                  "There are",
                  T[isAgeOver64 == TRUE, N],
                  T[isAgeOver64 == TRUE, N] / T[, sum(N)] * 100,
                  "unique (memberID, yearEnding) combinations where age > 64"))
}
## Warning: There are **170 (0.01%)** unique (memberID, yearEnding)
## combinations where age > 64
rm(T, test)

Create variables monthsEnrolledPriorQtr and monthsEnrolledPriorYr that show the number of months a member was enrolled during the three months, or one year, ending with the current study period (yearEnding).

f <- sprintf("%s\\%s", pathStaged, "Member_Months_LU.RData")
file.info(f)[c("size", "mtime")]
##                                                                                 size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\Member_Months_LU.RData 4624609
##                                                                                            mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\Member_Months_LU.RData 2015-07-17 16:49:27
load(f, verbose=TRUE)
## Loading objects:
##   metadata
##   Member_Months_LU
yearEndings <- sort(unique(mem_detail_Colorado$yearEnding, by=NULL))
years <- format(as.Date(yearEndings), "%Y")
months <- format(as.Date(yearEndings), "%b")
month_ends <- paste(months, years, sep="_")
for (i in 1:length(yearEndings)) {
  temp <- data.table(memberID = Member_Months_LU$memberID, yearEnding=as.Date("1900-01-01"))
  temp$yearEnding <- as.Date(yearEndings[i])
  column_end <- which(colnames(Member_Months_LU) == month_ends[i])
  column_start3  <- column_end -  2
  column_start12 <- column_end - 11
  temp$x <- rowSums(Member_Months_LU[, column_start3:column_end, with=FALSE])
  if (column_start12 < 0) {
    temp$y <- rowSums(Member_Months_LU[, 2:column_end, with=FALSE])
  } else {
    temp$y <- rowSums(Member_Months_LU[, column_start12:column_end, with=FALSE])
  }
  setnames(temp,
           old = c("x", "y"),
           new = c("monthsEnrolledPriorQtr", "monthsEnrolledPriorYr"))
  if (exists("enroll")) {enroll <- rbind(enroll, temp)} 
  else                  {enroll <- temp}
  rm(temp)
}
mem_detail_Colorado <- merge(mem_detail_Colorado, 
                             enroll, 
                             by = c("memberID", "yearEnding"),
                             all.x=TRUE,
                             sort=FALSE)
rm(Member_Months_LU, enroll)
gc()
##             used   (Mb) gc trigger    (Mb)   max used    (Mb)
## Ncells   3221238  172.1    5241317   280.0    5241317   280.0
## Vcells 718760226 5483.8 1859916643 14190.1 1859914151 14190.1

Drop rows from enroll if the member wasn’t enrolled in the last 12 months

mem_detail_Colorado <- mem_detail_Colorado[!monthsEnrolledPriorYr == 0]

Check.

mem_detail_Colorado[, .N, list(monthsEnrolledPriorQtr)][, prop := N / sum(N)][order(monthsEnrolledPriorQtr)]
##    monthsEnrolledPriorQtr       N       prop
## 1:                      0  419232 0.15252654
## 2:                      1  246408 0.08964907
## 3:                      2  140973 0.05128932
## 4:                      3 1941971 0.70653507
mem_detail_Colorado[, .N, list(monthsEnrolledPriorYr )][, prop := N / sum(N)][order(monthsEnrolledPriorYr )]
##     monthsEnrolledPriorYr       N       prop
##  1:                     1  118533 0.04312511
##  2:                     2  118427 0.04308655
##  3:                     3  118616 0.04315531
##  4:                     4   95434 0.03472115
##  5:                     5  101911 0.03707764
##  6:                     6  112143 0.04080028
##  7:                     7   97726 0.03555503
##  8:                     8  105613 0.03842451
##  9:                     9  182508 0.06640074
## 10:                    10  194293 0.07068840
## 11:                    11  126713 0.04610119
## 12:                    12 1376667 0.50086408

Check the sort key. Should be

  • memberID
  • yearEnding

Only print warning if not true.

if (!identical(key(mem_detail_Colorado), c("memberID", "yearEnding"))) {
  warning("Sort key for `mem_detail_Colorado` is not (`memberID`, `yearEnding`)")
  warning("Key variables:")
  warning(sprintf("  %s", key(mem_detail_Colorado)))
}

5.6 Save to RData and Stata datasets

Ignore save.dta13 warning. See this issue.

Save full datasets.

clientSnapshot <- D0
f <- sprintf("%s\\%s", pathStaged, "clientSnapshot")
metadata <- makeMetadata("makeClientSnapshot.Rmd")
system.time(save(metadata, clientSnapshot, file=sprintf("%s.RData", f)))
##    user  system elapsed 
##  126.63    0.29  127.13
system.time(save.dta13(clientSnapshot, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
##  508.89   26.97  537.13
f <- sprintf("%s\\%s", pathStaged, "mem_detail_Colorado")
metadata <- makeMetadata("makeClientSnapshot.Rmd")
system.time(save(metadata, mem_detail_Colorado, file=sprintf("%s.RData", f)))
##    user  system elapsed 
##   55.32    0.11   55.49
system.time(save.dta13(mem_detail_Colorado, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
##  210.16   11.06  221.61
rbind(file.info(sprintf("%s.RData", f))[c("size", "mtime")],
      file.info(sprintf("%s.dta", f))[c("size", "mtime")])
##                                                                                      size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_Colorado.RData  15777804
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_Colorado.dta   923534986
##                                                                                               mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_Colorado.RData 2015-07-17 17:05:57
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_Colorado.dta   2015-07-17 17:09:40
# str(clientSnapshot)
# str(mem_detail_Colorado)

Save 5% test sample datasets.

clientSnapshot <- D0[isSample5 == TRUE]
f <- sprintf("%s\\%s", pathStaged, "clientSnapshotSample5")
metadata <- makeMetadata("makeClientSnapshot.Rmd")
system.time(save(metadata, clientSnapshot, file=sprintf("%s.RData", f)))
##    user  system elapsed 
##    6.41    0.00    6.41
system.time(save.dta13(clientSnapshot, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
##   25.25    1.23   26.65
mem_detail_Colorado <- mem_detail_Colorado[isSample5 == TRUE]
f <- sprintf("%s\\%s", pathStaged, "mem_detail_ColoradoSample5")
metadata <- makeMetadata("makeClientSnapshot.Rmd")
system.time(save(metadata, mem_detail_Colorado, file=sprintf("%s.RData", f)))
##    user  system elapsed 
##    2.71    0.00    2.71
system.time(save.dta13(mem_detail_Colorado, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
##   10.23    0.61   10.86
rbind(file.info(sprintf("%s.RData", f))[c("size", "mtime")],
      file.info(sprintf("%s.dta", f))[c("size", "mtime")])
##                                                                                            size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_ColoradoSample5.RData   864332
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_ColoradoSample5.dta   45995542
##                                                                                                      mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_ColoradoSample5.RData 2015-07-17 17:10:21
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_ColoradoSample5.dta   2015-07-17 17:10:34

Clean up.

rm(clientSnapshot, mem_detail_Colorado)
gc()
##             used   (Mb) gc trigger    (Mb)   max used    (Mb)
## Ncells   3223071  172.2    5241317   280.0    5241317   280.0
## Vcells 607149058 4632.2 1859916643 14190.1 1859914151 14190.1

6 Claims

The Colorado data has two claims data files:

  1. Claim header, and
  2. Claim line

The key variables linking the datasets are

There is a 1:many match between claim header and claim line.

A big portion of the processing is done by the SAS script, makeClaims.sas. The output is a CSV file to be read in by R later on in this script.

system.time(callSAS("makeClaims.sas", path=pathScripts))
## /* 
## Set library paths.
## Set options.
##  */
## %let pathData = E:\Share\DataRepository\Colorado Medicaid;
## libname PreSt "&pathData\PreStaged" access=readonly;
## libname Staged "&pathData\Staged";
## options fmtsearch = (Staged);
## options formchar="|----|+|---+=|-/\<>*";
## options ls=132 ps=max;
## 
## 
## /* 
## Show which variables appear in both the claim header and claim line datasets
##  */
## proc contents data=PreSt.claimHeader order=varnum out=Work.claimHeaderCol noprint;
## run;
## proc contents data=PreSt.claimLine order=varnum out=Work.claimLineCol noprint;
## run;
## proc sql;
##   select
##     A.name label="nameOnHeaderTable" as nameOnHeaderTable,
##     B.name label="nameOnLineTable" as nameOnLineTable,
##     coalesce(A.label, B.label) as label
##   from
##     Work.claimHeaderCol A full join
##     Work.claimLineCol B on (A.name = B.name)
##   ;
## quit;
## 
## 
## /* 
## MAIN QUERY
##  */
## 
## /* 
## # Exclusions, per Rich
## 
## From: Lindrooth, Richard [mailto:RICHARD.LINDROOTH@UCDENVER.EDU] 
## Sent: Thursday, July 02, 2015 3:58 PM
## To: Benjamin Chan
## Subject: RE: ACC State Reports
## 
## Yes, these seem really high.  At first glance I thought perhaps these were PMPY
## figures.  One note of caution on the Median is that there are quite a few people
## with zero expenditures.
## 
## The total that I calculated were based on all paid claims from the  Claim_Header
## (Inpat facility and Pharma) and Claim_Line (Everything Else).
## 
## I would double-check your clnt_ids and make sure they aren't rounded.
## 
## Another step is to toss the encounter claims:   
## batch_doc_typ_cd~="E" & batch_doc_typ_cd~="F"   
## Though this probably didnâ<U+0080><U+0099>t matter.
## 
## However, I also used only paid claims:
## 
## clm_sts_cd=="P"
## 
## Also on the Line item data I dropped:
## 
## clm_type_cd~="A"  "Pharma"
## clm_type_cd~="B"  "Inpatient"
## clm_type_cd~="D"  "SNF"
## clm_type_cd~="W"  "HCBS Waiver"  (I'm not sure why at this point, it was a seat of the pants decision...)
## 
## On the Header I kept :
## 
## clm_type_cd=="A"  "Pharma"
## clm_type_cd=="B"  "Inpatient"
## clm_type_cd=="D"  "SNF"
## 
## 
## Most of the following dropped out when I limited to regular Medicaid: 
## 
## clm_type_cd=="M"  "Part A xover"
## clm_type_cd=="N"  "Part B xover"
## clm_type_cd=="O"  "Part A & B xover"
## 
## 
## Where regular Medicaid is:
## 
## Clnt_elig_type_cd==4, 5, 6, 7, 8, 17 (FFS but enhanced services) 
##  */
## 
## /* 
## From: Lindrooth, Richard [mailto:RICHARD.LINDROOTH@UCDENVER.EDU] 
## Sent: Thursday, July 02, 2015 6:04 PM
## To: Benjamin Chan
## Subject: Re: ACC State Reports
## 
## I don't think so, I think they were claims that were rejected and then
## resubmitted.  They may not have had all of the necessary documentation, etc...
## I think it makes sense to drop them.  Colorado is FFS so they eventually pay for
## pretty much everything that was done.
## 
## In the documentation it suggests limiting it to paid claims.  Also note that
## even with paid claims there are offsetting  negative claims.  That may be
## affecting the repricing.  The offsetting claims sometimes have different
## TCNs...
## 
## On the line item, collapsing by the clnt_id, dates of services, prov_bill_id,
## units and proc_cd is probably sufficient to cancel these out.  In the inpatient
## I noticed the resubmitted claims had different DRG codes, this makes it harder,
## but I used the admit and discharge dates for these.
## 
## Rich
## 
## 
## From: Benjamin Chan <chanb@ohsu.edu>
## Date: Thursday, July 2, 2015 at 5:08 PM
## To: richard lindrooth <richard.lindrooth@ucdenver.edu>
## Subject: RE: ACC State Reports
## 
## But aren't those services that occurred but weren't paid for? In other words,
## they represent real utilization and should be accounted for?
##  
## 
## From: Lindrooth, Richard [mailto:RICHARD.LINDROOTH@UCDENVER.EDU] 
## Sent: Thursday, July 02, 2015 4:06 PM
## To: Benjamin Chan
## Subject: RE: ACC State Reports
##  
## Also, to add on to the last e-mail,  I dropped pd_amt==0 .   This could lead to
## the really high numbers when you reprice. 
##  */
## 
## /* 
## # How to deal with spending variables
## 
## From: Ly, Melissa [mailto:Melissa.Ly@state.co.us] 
## Sent: Wednesday, April 08, 2015 8:53 AM
## To: Duke, Jodi Kay; Dalzell, Joel; Burton, Byron; Whalen, Tom; Benjamin Chan; Lindrooth, Richard; John McConnell
## Subject: RE: CU Denver/CO Medicaid Data Extract - Followup Questions for 4/8/15
## 
## > 3. Claim line amounts by CLM_TCN do not sum to claim header amounts
## >    a. ~2% for paid amount
## >    b. ~6% for allowed charged amount
## >    c. ~ 3% for billed amount
## >    d. ~14% for copay amount
## >    e. ~ 0.1% for Medicare paid amount
## >    f. ~ 1.5% for TPL amount
## >    g. Are these unusual?
## >    h. Should we ignore claim header amounts and use the sum of the claim line amounts?
## 
## * True, header and line $â<U+0080><U+0099>s do not always line up (sometimes they do).  Certain
##   claims are adjudicated at the header and others at the line.  The Header info
##   should be complete to get totals for all claim types.  Line adjudicated claims
##   costs will sum to the header paid amount, and you can get line level detail
##   (paid amounts for specific procedures, for example).
## * Certain line claims pay at the line:
##     * E, K, F, H, I, L, W, and N
## * Certain line claims pay at the header:
##     * C, J, O
## * Certain header claims pay at the header
##     * B, D, M
## * Pharmacy claims are paid at the header
##     * A
## 
## > 4. ~13% of claim lines with the same TCN that have more than 1 claim line
## >    do not have the same service dates as the associated claim header
## 
## * True.  Line adjudicated claims may have Dates of Service that are not captured
##   in the one DOS field available on the Claim Header.
## * Claim headers contain summary information (earliest first date of service,
##   the latest last date of service, and total payment that is NOT the sum of the
##   line payment (except if you are looking at C, J, and O claims)).
##  */
## 
## /* 
## Exclude claims with claim type = "A"
## They are pharmacy claims
## 
## > You can get easily get `CLNT_ID` by linking the `CLM_TCN` from the Rx Claim
## > Line data to the `CLM_TCN` in the Claim Header Table.  Every `CLM_TCN` in the
## > Rx line table will have a `CLM_TCN` in the Claims Header Table.  As we
## > discussed on the last call, would recommend staying away from the RX line
## > table.  Use the Claim Header Table with Claim Type = *A* to get Rx
## > information.
##  */
## 
## /* 
## * Batch Doc Type
## * Claim Type
## * Service category
## These map uniquely across claim header and claim line (matched on CLM_TCN).
## (Almost uniquely for Service category, very small percentage of TCNs have non-unique values)
## 
## => Keep the value from the claim line dataset
##  */
## proc sql;
##   create table Work.lookup as
##   select CLNT_ID, dateCoverageBegin, dateCoverageEnd 
##   from Staged.clientSnapshot
##   /* where isSample1 */
##   ;
## 
##   create table Work.claimHeader as
##   select
##     A.CLNT_ID,
##     "D" || A.CLNT_ID as memberID,
##     A.CLM_TCN,
##     A.CLM_TYPE_CD format=$char. as claimType,
##     A.BATCH_DOC_TYP_CD format=$char. as batchDocType,
## /* 
##     The datepart function will return a warning.
##     > NOTE: Invalid (or missing) arguments to the DATEPART function have caused the function to return a missing value.
##     Missing values don't appear to seriously break anything.
##  */
##     datepart(A.SRV_FROM_DT) format=yymmdd10. as dateFirstSvc,
##     datepart(A.SRV_TO_DT) format=yymmdd10. as dateLastSvc,
##     year(calculated dateFirstSvc) as year,
##     mdy(ceil(month(calculated dateFirstSvc) / 3) * 3,
##         case ceil(month(calculated dateFirstSvc) / 3) * 3
##             when  3 then 31
##             when  6 then 30
##             when  9 then 30
##             when 12 then 31
##             else .
##             end,
##         calculated year)
##       format=yymmdd10. as yearEnding,
##     datepart(A.ADMIT_DT) format=yymmdd10. as dateAdmit,
##     datepart(A.DISCHARGE_DT) format=yymmdd10. as dateDisch,
##     max(1, calculated dateDisch - calculated dateAdmit) as los,
##     A.ADMIT_TYPE_CD format=$char. as admSrc,
##     A.BILL_TYPE_CD format=$char. as typeOfBill,
##     A.DRG_CMS_CD format=$char. as drg,
##     /* A.ORIG_DRG_CD format=$char., Don't want this DRG code per 2015-04-08 conference call with HCPF*/
##     A.PATIENT_STS_CD format=$char. as cde_patient_status,
##     A.POC_CD format=$char.,
##     A.CLM_STS_CD as clmstatus,
##     A.PD_AMT as amtPaid,
##     A.ALLOW_CHRG_AMT as amtAllowed,
##     A.BILL_AMT as amtBilled,
##     A.COPAY_AMT as amtCopay,
##     A.MCARE_PD_AMT as amtMedicarePaid,
##     A.TPL_AMT as amtTPL,
##     1 as qtyUnitsBilled,
##     A.prov_bill_id,
##     A.isSample1,
##     A.isSample5
##   from
##     PreSt.claimHeader A
##     inner join Work.lookup C
##     on (A.CLNT_ID = C.CLNT_ID & (C.dateCoverageBegin <= datepart(A.SRV_FROM_DT) <= C.dateCoverageEnd))
##   where
##     /* A.isSample1 & */
##     A.BATCH_DOC_TYP_CD ^in ("E", "F") &
##     A.CLM_STS_CD = "P" &
##     A.CLM_TYPE_CD in ("B", "D") &
##     A.PD_AMT ^= 0
##   ;
## 
##   create table Work.claimLine as 
##   select
##     B.CLNT_ID,
##     "D" || B.CLNT_ID as memberID,
##     B.CLM_TCN as CLM_TCN,
##     B.CLM_TYPE_CD format=$char. as claimType,
##     B.BATCH_DOC_TYP_CD format=$char. as batchDocType,
## /* 
##     The datepart function will return a warning.
##     > NOTE: Invalid (or missing) arguments to the DATEPART function have caused the function to return a missing value.
##     Missing values don't appear to seriously break anything.
##  */
##     datepart(B.SRV_FROM_DT) format=yymmdd10. as dateFirstSvc,
##     datepart(B.SRV_TO_DT) format=yymmdd10. as dateLastSvc,
##     year(calculated dateFirstSvc) as year,
##     mdy(ceil(month(calculated dateFirstSvc) / 3) * 3,
##         case ceil(month(calculated dateFirstSvc) / 3) * 3
##             when  3 then 31
##             when  6 then 30
##             when  9 then 30
##             when 12 then 31
##             else .
##             end,
##         calculated year)
##       format=yymmdd10. as yearEnding,
##     B.PROC_CD format=$char. as cpt,
##     B.PROC_MOD_1_CD format=$char. as cptModifier1,
##     B.PROC_MOD_2_CD format=$char. as cptModifier2,
##     B.REV_CD format=$char. as ubRev,
##     B.COS_CD format=$char. as srvCat,
## /* 
##     The INPUT function will return a note about invalid strings.
##     Ignore the note, missing values will be assigned.
##     NOTE: Invalid string.
##     NOTE: Invalid argument to function INPUT. Missing values may be generated.
##  */
##     input(B.PLACE_OF_SRV_CD, 2.0) as pos,
##     B.CLM_STS_CD as clmstatus,
##     B.PD_AMT as amtPaid,
##     B.ALLOW_CHRG_AMT as amtAllowed,
##     B.BILL_AMT as amtBilled,
##     B.COPAY_AMT as amtCopay,
##     B.MCARE_PD_AMT  as amtMedicarePaid,
##     B.TPL_AMT as amtTPL,
##     B.BILL_UOS_QTY as qtyUnitsBilled,
##     B.LINE_LEVEL_UNITS_ALLOWED as qtyUnitsMax,
##     B.isSample1,
##     B.isSample5
##   from
##     PreSt.claimLine B
##     inner join Work.lookup C
##     on (B.CLNT_ID = C.CLNT_ID & (C.dateCoverageBegin <= datepart(B.SRV_FROM_DT) <= C.dateCoverageEnd))
##   where
##     /* B.isSample1 & */
##     B.BATCH_DOC_TYP_CD ^in ("E", "F") &
##     B.CLM_STS_CD = "P" &
##     B.CLM_TYPE_CD ^in ("A", "B", "D", "W") &
##     B.PD_AMT ^= 0
##   ;
## 
##   create table Staged.claims as 
##   select "Header" as fileSource, A.* from Work.claimHeader A outer union corr
##   select "Line"   as fileSource, B.* from Work.claimLine   B
##   ;
## 
##   select 
##     fileSource, 
##     count(*) format=comma12.0 as countRows,
##     count(*) / (select count(*) from Staged.claims) format=percent10.4 as propRows
##   from Staged.claims 
##   group by fileSource
##   ;
## 
## quit;
## 
## 
## /* 
## Check sampling indicators
##  */
## proc sql;
##   select
##     isSample1,
##     isSample5,
##     count(*) as countRows
##   from
##     Staged.claims
##   group by
##     isSample1,
##     isSample5
##   ;
## quit;
## 
## 
## /* 
## Make indexes
##  */
## proc datasets library=Staged;
##   modify claims;
##   index create memberID;
##   index create CLM_TCN;
## run;
## 
## 
## /* 
## Make colClasses dataset.
## Output for later use in R.
##  */
## proc contents data=Staged.claims order=varnum out=Work.contents noprint;
## run;
## proc sql;
##   create table Work.colClasses as
##   select
##     case
##       when type = 2 then "character"
##       when prxmatch("/\$/", format) then "character"
##       when prxmatch("/YYMMDD/", format) then "character"
##       when formatd > 0 then "numeric"
##       else "integer"
##     end as colClass
##   from Work.contents
##   order by
##     varnum
##   ;
## quit;
## 
## 
## /* 
## Export datasets to CSV files for later use in R
##  */
## filename f "&pathData\Staged\claims.csv";
## proc export data=Staged.claims outfile=f dbms=csv replace;
## run;
## filename f "&pathData\Staged\colClasses.csv";
## proc export data=Work.colClasses outfile=f dbms=csv replace;
## run;
## No errors
## See H:/CHSE/Projects/DataProcessing/ColoradoMedicaid/StagingCode\makeClaims.log for details.
##    user  system elapsed 
##    0.03    0.01 1846.69

6.1 Differences from staging Oregon DMAP and APAC data

Some processing differences from the staging of the Oregon DMAP and APAC data is necessary.

The Oregon DMAP and APAC data was primarily processed using R. A larger chunk of the processing of the Colorado Medicaid data happens in SAS. The migration was mainly influenced by speed/memory considerations. The migrated processes are:

  • Include only claims matched to an included enrollment record
  • Create year variable
  • Create yearEnding variable
  • Create los variable
  • Fix missing values

Things that are not done in this script.

  • Read in ICD-9 diagnosis and procedure codes
    • In the HCPF system, these data elements are in separate datasets

6.2 Load helper objects

Load helper objects create by makeHelpers.Rmd.

f <- sprintf("%s\\%s", pathTemp, "helpers.RData")
file.info(f)[c("size", "mtime")]
##                                                              size
## E:\\Share\\Temp\\chanb\\Colorado Medicaid\\helpers.RData 14907116
##                                                                        mtime
## E:\\Share\\Temp\\chanb\\Colorado Medicaid\\helpers.RData 2015-07-17 15:56:58
load(f)

6.3 Read data file

f <- sprintf("%s\\colClasses.csv", pathStaged)
colClasses <- fread(f)
file.remove(f)
## [1] TRUE
f <- sprintf("%s\\claims.csv", pathStaged)
D <- fread(f, colClasses=colClasses[, colClass], na.strings=na.strings, showProgress=FALSE)
# D <- D[isSample1 == TRUE]  # Uncomment this line for testing
D <- D[,
       `:=` (dateFirstSvc = as.Date(dateFirstSvc),
             dateLastSvc = as.Date(dateLastSvc),
             yearEnding = as.Date(yearEnding),
             dateAdmit = as.Date(dateAdmit),
             dateDisch = as.Date(dateDisch))]
# str(D)

6.3.1 Fix some quirks

  • Pad the non-missing DRG codes with leading zeros to length 3
  • Pad the non-missing UB revenue codes with leading zeros to length 4
  • Add factor labels to
    • Batch document type
    • Claim type
D <- D[!is.na(drg), drg := sprintf("%03d", as.numeric(drg))]
D <- D[!is.na(ubRev), ubRev := sprintf("%04d", as.numeric(ubRev))]
D <- D[, batchDocType := factor(batchDocType, levels=lBatchDocType, labels=names(lBatchDocType))]
D <- D[, claimType := factor(claimType, levels=lClaimType, labels=names(lClaimType))]

6.3.2 Quirks that need fixes

Quantities (original variable name: BILL_UOS_QTY). A very small percentage of the quantities are ridiculous.

tails <- c(0, 1E-5, 1E-4, 1E-3, 1E-2)
quantile(D[, qtyUnitsBilled], prob=c(tails, 0.5), na.rm=TRUE)
##       0%   0.001%    0.01%     0.1%       1%      50% 
## -8212013    -1001     -216      -43       -2        1
quantile(D[, qtyUnitsBilled], prob=c(0.5, 1-rev(tails)), na.rm=TRUE)
##     50%     99%   99.9%  99.99% 99.999%    100% 
##       1      20     230    1600    3200 9072010

6.3.3 Map claim type to values compatible with Oregon DMAP values

Claim type in the Colorado HCPF data has different values than the Oregon data See lClaimType.

lClaimType
##              PHARMACY CLAIM                   INPATIENT 
##                         "A"                         "B" 
##                  OUTPATIENT            NURSING FACILITY 
##                         "C"                         "D" 
##      PRACTITIONER/PHYSICIAN                      DENTAL 
##                         "E"                         "F" 
##      INDEPENDENT LABORATORY              MEDICAL SUPPLY 
##                         "H"                         "I" 
##                 HOME HEALTH                       EPSDT 
##                         "J"                         "K" 
##              TRANSPORTATION      MCARE PART A CROSSOVER 
##                         "L"                         "M" 
##      MCARE PART B CROSSOVER MCARE UB04 PART B CROSSOVER 
##                         "N"                         "O" 
##                 HCBS WAIVER       FINANCIAL TRANSACTION 
##                         "W"                         "X" 
##         REPLACEMENT REQUEST              CREDIT REQUEST 
##                         "Y"                         "Z" 
##        CICP INPATIENT CLAIM       CICP OUTPATIENT CLAIM 
##                         "1"                         "2" 
##                  CAPITATION                     NO DATA 
##                         "3"                          ""

The problem

From: Benjamin Chan [mailto:chanb@ohsu.edu] 
Sent: Tuesday, June 09, 2015 12:29 PM
To: Lindrooth, Richard; Duke, Jodi Kay
Cc: John McConnell; Stephanie Renfro
Subject: Claim type crosswalk

Rich, Jodi,

I'm realizing that the values in the claim type field in the HCPF data do not
map 1:1 to the claim type field in the Oregon Medicaid data. I need to map claim
types because it's one of the fields we use to bucket prices. Any thoughts on
how to work around this problem would be appreciated. Details are below.

Here's is my incomplete mapping. As you can see, there's a lot of empty cells on
either the Colorado side (yellow) or the Oregon side (blue). I'm not fully
confident that the mapping I do have is even correct.

claimTypeMappingBefore.png

The solution

Create a new variable called claimTypeOR. This maps claimType to values compatible with Oregon DMAP values.

From: Lindrooth, Richard [mailto:RICHARD.LINDROOTH@UCDENVER.EDU] 
Sent: Tuesday, June 09, 2015 11:54 AM
To: Benjamin Chan; Duke, Jodi Kay
Cc: John McConnell; Stephanie Renfro
Subject: RE: Claim type crosswalk

Hi, 
I would put the Oregon Long term Care with the Colorado Home Health and Nursing
Facility and check to see if they are comparable.

I don't know where Independent Lab/Medical Supply claims would fall in the
Oregon data.  The could be checked using CPT codes. In CO, I would guess that
the hospital & physician-office lab claims are included in the inpatient &
outpatient claim types and not in the independent lab claims.  If there is a
place of service code in the Oregon data that might be used to sort out
independent lab and the Hospital/Physician Office lab claims.

The CICP claims in Colorado are related to an indigent care program at Denver
Health (and perhaps other providers).

We could check into the Colorado UB04 meaning.  It may be how they distinguish
professional service Part B crossover from outpatient Part B crossover.

Other notes:

  • Independent lab (pos == 81) in the Oregon DMAP claims was almost always billed as professional claims, and to a lesser extent as professional crossover claims
  • Medical supply (grepl("^A[4-8]", cpt)) in the Oregon DMAP claims was almost always billed as professional claims
  • EPSDT (grepl("^9[069]", cpt)) in the Oregon DMAP claims was almost always billed as professional claims, unless
    • If place of service was outpatient hospital (pos == 22) then claim type was almost always outpatient, and to a lesser extent outpatient crossover
  • Transportation (pos == 41 | grepl("^A0", cpt)) in the Oregon DMAP claims was almost always billed as professional claims, and to a lesser extent as professional crossover claims
  • HCBS (Home and community-based services) Waiver will be lumped with long term care
D <- D[claimType == "PHARMACY CLAIM"             , claimTypeOR := "P"]
D <- D[claimType == "INPATIENT"                  , claimTypeOR := "I"]
D <- D[claimType == "OUTPATIENT"                 , claimTypeOR := "O"]
D <- D[claimType == "NURSING FACILITY"           , claimTypeOR := "L"]
D <- D[claimType == "PRACTITIONER/PHYSICIAN"     , claimTypeOR := "M"]
D <- D[claimType == "DENTAL"                     , claimTypeOR := "D"]
D <- D[claimType == "INDEPENDENT LABORATORY"     , claimTypeOR := "M"]
D <- D[claimType == "MEDICAL SUPPLY"             , claimTypeOR := "M"]
D <- D[claimType == "HOME HEALTH"                , claimTypeOR := "L"]
D <- D[claimType == "EPSDT"                                   , claimTypeOR := "M"]
D <- D[claimType == "EPSDT"                      & pos == "22", claimTypeOR := "O"]
D <- D[claimType == "TRANSPORTATION"             , claimTypeOR := "M"]
D <- D[claimType == "MCARE PART A CROSSOVER"     , claimTypeOR := "A"]
D <- D[claimType == "MCARE PART B CROSSOVER"     , claimTypeOR := NA]
D <- D[claimType == "MCARE UB04 PART B CROSSOVER", claimTypeOR := NA]
D <- D[claimType == "HCBS WAIVER"                , claimTypeOR := "L"]
D <- D[claimType == "FINANCIAL TRANSACTION"      , claimTypeOR := NA]
D <- D[claimType == "REPLACEMENT REQUEST"        , claimTypeOR := NA]
D <- D[claimType == "CREDIT REQUEST"             , claimTypeOR := NA]
D <- D[claimType == "CICP INPATIENT CLAIM"       , claimTypeOR := NA]
D <- D[claimType == "CICP OUTPATIENT CLAIM"      , claimTypeOR := NA]
D <- D[claimType == "CAPITATION"                 , claimTypeOR := NA]
D <- D[claimType == "NO DATA"                    , claimTypeOR := NA]

Check.

pathSource <- "E:\\Share\\DataRepository\\Colorado Medicaid\\Medicaid_UCDSPH"
f <- "VALID_VALUES.TXT"
validValues <- fread(sprintf("%s\\\\%s", pathSource, f), sep="|", stringsAsFactors=FALSE)
valuesCM <- validValues[VALID_VALUE_SRC_CD == "CM",
                        list(VALID_VALUE_SRC_CD,
                             VALID_VALUE_CD, VALID_VALUE_DSC)]
D[,
  .N,
  list(claimType,
       valuesCM$VALID_VALUE_CD[unclass(claimType)],
       claimTypeOR)][,
                     prop := sprintf("%.2f%%", 100 * N / sum(N))][order(claimType)]
##                       claimType valuesCM claimTypeOR        N   prop
##  1:                   INPATIENT        B           I   230284  0.38%
##  2:                  OUTPATIENT        C           O 21489483 35.80%
##  3:            NURSING FACILITY        D           L      245  0.00%
##  4:      PRACTITIONER/PHYSICIAN        E           M 18736047 31.21%
##  5:                      DENTAL        F           D 10780905 17.96%
##  6:      INDEPENDENT LABORATORY        H           M  3268746  5.45%
##  7:              MEDICAL SUPPLY        I           M  1055532  1.76%
##  8:                 HOME HEALTH        J           L  1099578  1.83%
##  9:                       EPSDT        K           M  3022653  5.04%
## 10:                       EPSDT        K           O    95725  0.16%
## 11:              TRANSPORTATION        L           M   238967  0.40%
## 12:      MCARE PART B CROSSOVER        N          NA     3207  0.01%
## 13: MCARE UB04 PART B CROSSOVER        O          NA     1912  0.00%
D[is.na(claimTypeOR),
  .N,
  list(claimType,
       valuesCM$VALID_VALUE_CD[unclass(claimType)],
       claimTypeOR)][,
                     prop := sprintf("%.2f%%", 100 * N / sum(N))][order(claimType)]
##                      claimType valuesCM claimTypeOR    N   prop
## 1:      MCARE PART B CROSSOVER        N          NA 3207 62.65%
## 2: MCARE UB04 PART B CROSSOVER        O          NA 1912 37.35%
D[,
  .N,
  list(claimTypeOR)][,
                     prop := sprintf("%.2f%%", 100 * N / sum(N))][order(claimTypeOR)]
##    claimTypeOR        N   prop
## 1:           D 10780905 17.96%
## 2:           I   230284  0.38%
## 3:           L  1099823  1.83%
## 4:           M 26321945 43.85%
## 5:           O 21585208 35.96%
## 6:          NA     5119  0.01%
valuesPI <- validValues[VALID_VALUE_SRC_CD == "PI",
                        list(VALID_VALUE_SRC_CD,
                             VALID_VALUE_CD, VALID_VALUE_DSC)]

Open ISSUE This solution still leaves a small percentage of claims without an Oregon DMAP-like claim type value.

message(sprintf("Number of claims without an Oregon DMAP-like claim type value:\n%s (%.2f%%)",
                format(nrow(D[is.na(claimTypeOR)]), big.mark=","),
                nrow(D[is.na(claimTypeOR)]) / nrow(D) * 100))
## Number of claims without an Oregon DMAP-like claim type value:
## 5,119 (0.01%)

6.3.4 Fix missing values

  • Recode drg values that are not valid DRG codes to NA.
  • Recode cpt values that are not valid CPT (5 digits) or HCPCS (1 character + 4 digits) codes to NA.
    • Allow for CPT Level II codes (4 digits + F) and Level III codes (4 digits + T).
  • Recode cptModifier1 and cptModifier2 values that are not valid CPT or HCPCS modifiers to NA.
  • DO NOT DO Recode ICD-9 diagnosis codes that do not have a leading character between 0-9, E, or V, followed by 2-4 digits to NA.
    • Will be done by makeICD9.Rmd
  • DO NOT DO Recode ICD-9 procedure codes that do not have 3-4 digits to NA.
    • Will be done by makeICD9.Rmd
  • Recode ubRev values that are not 1-4 characters in length and containing only digits to NA.
  • DO NOT DO Recode goofy quantity of units billed to 1 (should be done before recoding cpt since it needs to use the original cpt value in the check).
    • This was used to fix Oregon DMAP claims where it was obvious that dates were entered in the quantity field
recodeToNA <- function (x, regex, invert=TRUE) {
  # If invert == TRUE (default), then regex is a regular expression of VALID values,
  # and the expression needs to be inverted
  if (invert == TRUE) {
    x[!is.na(x) & !grepl(regex, x)] <- NA
  } else {
    x[!is.na(x) & grepl(regex, x)] <- NA
  }
  x
}
D <- D[,
       `:=` (drg = recodeToNA(drg,
                              "^[0-9]{3}$",
                              invert=TRUE),
             cpt = recodeToNA(cpt,
                              "(^[0-9]{5}$)|(^[A-Z][0-9]{4}$)|(^[0-9]{4}[FT]$)",
                              invert=TRUE),
             cptModifier1 = recodeToNA(cptModifier1,
                                       "(^[0-9A-Z]{2}$)",
                                       invert=TRUE),
             cptModifier2 = recodeToNA(cptModifier2,
                                       "(^[0-9A-Z]{2}$)",
                                       invert=TRUE),
             ubRev = recodeToNA(ubRev,
                                "^[0-9]{1,4}$",
                                invert=TRUE))]

6.3.5 Create bucketID and amtAllowedUnit

A list of CPT/HCPCS pricing modifiers can be found in Understanding Procedural Coding: A Worktext. Only look at the first modifier. This is a convenience. There are instances where the first modifier is not a pricing modifier but the second is. So, we probably want to incorporate the second modifier in the future.

Use claimTypeOR instead of claimType.

pricingModifiers <- c("AA", "AD", "AH", "AJ", "AS", "GM", "QB", "QK", "QU", 
                      "QX", "QY", "QZ", "SG", "TC", "UN", "UP", "UQ", "UR", 
                      "US", "22", "26", "50", "51", "52", "53", "54", "55", 
                      "56", "62", "66", "73", "74", "78", "80", "82", "99")
D <- D[,
       `:=` (bucketID = paste(ifelse(cptModifier1 %in% pricingModifiers, 
                                     paste(cpt, cptModifier1, sep="-"), 
                                     cpt), 
                              drg, 
                              ubRev, 
                              claimTypeOR, 
                              sep="/"),
             amtAllowedUnit = amtAllowed / qtyUnitsBilled)]
rm(pricingModifiers)

6.3.6 Create BETOS variables

Create groupings. Optimize using numeric vector indexing (see Nesterko.com, part (b))

idx1 <- match(D$cpt, names(codeBetos))
idx2 <- match(D$cpt, names(facBetos ))
D <- D[,
       `:=` (codeBetos = codeBetos[idx1],
             facBetos  = facBetos [idx2])]
rm(idx1, idx2)

Check.

D[, .N, list(facBetos, codeBetos)][, prop := sprintf("%.2f%%", N / sum(N) * 100)][order(facBetos, codeBetos)]
##              facBetos codeBetos        N   prop
##   1:            E & M       M1A  1178113  1.96%
##   2:            E & M       M1B  7569934 12.61%
##   3:            E & M       M2A   156722  0.26%
##   4:            E & M       M2B   407478  0.68%
##   5:            E & M       M2C   133479  0.22%
##  ---                                           
## 101:            Other       O1G  1667688  2.78%
## 102: Except./unclass.        Y1 11353427 18.92%
## 103: Except./unclass.        Y2   179593  0.30%
## 104: Except./unclass.        Z2   451049  0.75%
## 105:               NA        NA  7260195 12.10%

6.4 Save to RData and Stata datasets

Reset the key variables.

setkey(D, year, memberID)

Save full datasets.

claims <- D
f <- sprintf("%s\\%s", pathStaged, "claims_Colorado")
metadata <- makeMetadata("makeClaims.Rmd")
system.time(save(metadata, claims, file=sprintf("%s.RData", f)))
##    user  system elapsed 
## 1292.79    5.83 1301.14
system.time(save.dta13(claims, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
## 4205.51  153.88 4369.79
rbind(file.info(sprintf("%s.RData", f))[c("size", "mtime")],
      file.info(sprintf("%s.dta", f))[c("size", "mtime")])
##                                                                                    size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_Colorado.RData  1227834506
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_Colorado.dta   11164339586
##                                                                                           mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_Colorado.RData 2015-07-17 19:31:10
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_Colorado.dta   2015-07-17 20:44:12
# str(claims)

Save 5% test sample datasets.

claims <- D[isSample5 == TRUE]
f <- sprintf("%s\\%s", pathStaged, "claims_ColoradoSample5")
metadata <- makeMetadata("makeClaims.Rmd")
system.time(save(metadata, claims, file=sprintf("%s.RData", f)))
##    user  system elapsed 
##   61.54    0.25   61.89
system.time(save.dta13(claims, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
##  217.48    7.68  225.69
rbind(file.info(sprintf("%s.RData", f))[c("size", "mtime")],
      file.info(sprintf("%s.dta", f))[c("size", "mtime")])
##                                                                                         size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_ColoradoSample5.RData  61203542
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_ColoradoSample5.dta   549153142
##                                                                                                  mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_ColoradoSample5.RData 2015-07-17 20:45:33
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_ColoradoSample5.dta   2015-07-17 20:49:31

Clean up.

rm(claims)
gc()
##              used    (Mb) gc trigger    (Mb)   max used    (Mb)
## Ncells   31341871  1673.9   46090137  2461.5   46090137  2461.5
## Vcells 2919524356 22274.3 6239114692 47600.7 4647940320 35461.0

Delete temporary data files.

filenames <- list.files(pathStaged)
filenames <- sprintf("%s\\%s", pathStaged, filenames[grep("^claims\\.((csv))", list.files(pathStaged), ignore.case=TRUE)])
message(sprintf("Deleting file: %s\n", filenames))
## Deleting file: E:\Share\DataRepository\Colorado Medicaid\Staged\claims.csv
file.remove(filenames)
## [1] TRUE

7 Prescription Drug Claims

The Colorado data has two prescription drugs claims data files:

  1. Rx Claim header, and
  2. Rx Claim line

Include claims with claim type = “A”. They are pharmacy claims.

You can get easily get CLNT_ID by linking the CLM_TCN from the Rx Claim Line data to the CLM_TCN in the Claim Header Table.
Every CLM_TCN in the Rx line table will have a CLM_TCN in the Claims Header Table.
As we discussed on the last call, would recommend staying away from the RX line table. Use the Claim Header Table with Claim Type = A to get Rx information.

The key variables linking the datasets are

There is a 1:many match between claim header and claim line.

A big portion of the processing is done by the SAS script, makeClaims.sas. The output is a CSV file to be read in by R later on in this script.

system.time(callSAS("makeRxClaims.sas", path=pathScripts))
## /* 
## Set library paths.
## Set options.
##  */
## %let pathData = E:\Share\DataRepository\Colorado Medicaid;
## libname PreSt "&pathData\PreStaged" access=readonly;
## libname Staged "&pathData\Staged";
## options fmtsearch = (Staged);
## options formchar="|----|+|---+=|-/\<>*";
## options ls=132 ps=max;
## 
## 
## /* 
## Show which variables appear in both the claim header and claim line datasets
##  */
## proc contents data=PreSt.claimHeader order=varnum out=Work.claimHeaderCol noprint;
## run;
## proc contents data=PreSt.rxClaimHeader order=varnum out=Work.rxClaimHeaderCol noprint;
## run;
## proc contents data=PreSt.rxClaimLine order=varnum out=Work.rxClaimLineCol noprint;
## run;
## proc sql;
##   select
##     A.name label="nameOnHeaderTable" as nameOnHeaderTable,
##     A.type label="typeOnHeaderTable" as typeOnHeaderTable,
##     B.name label="nameOnRxHeaderTable" as nameOnRxHeaderTable,
##     B.type label="typeOnRxHeaderTable" as typeOnRxHeaderTable,
##     C.name label="nameOnRxLineTable" as nameOnRxLineTable,
##     C.type label="typeOnRxLineTable" as typeOnRxLineTable,
##     coalesce(A.label, B.label, C.label) as label
##   from
##     Work.claimHeaderCol A full join
##     Work.rxClaimHeaderCol B on (A.name = B.name) full join
##     Work.rxClaimLineCol C on (A.name = C.name)
##   order by
##     coalesce(A.name, B.name, C.name)
##   ;
## quit;
## 
## 
## /* 
## MAIN QUERY
##  */
## 
## /* 
## # How to deal with spending variables
## 
## From: Ly, Melissa [mailto:Melissa.Ly@state.co.us] 
## Sent: Wednesday, April 08, 2015 8:53 AM
## To: Duke, Jodi Kay; Dalzell, Joel; Burton, Byron; Whalen, Tom; Benjamin Chan; Lindrooth, Richard; John McConnell
## Subject: RE: CU Denver/CO Medicaid Data Extract - Followup Questions for 4/8/15
## 
## > 3. Claim line amounts by CLM_TCN do not sum to claim header amounts
## >    a. ~2% for paid amount
## >    b. ~6% for allowed charged amount
## >    c. ~ 3% for billed amount
## >    d. ~14% for copay amount
## >    e. ~ 0.1% for Medicare paid amount
## >    f. ~ 1.5% for TPL amount
## >    g. Are these unusual?
## >    h. Should we ignore claim header amounts and use the sum of the claim line amounts?
## 
## * True, header and line $â<U+0080><U+0099>s do not always line up (sometimes they do).  Certain
##   claims are adjudicated at the header and others at the line.  The Header info
##   should be complete to get totals for all claim types.  Line adjudicated claims
##   costs will sum to the header paid amount, and you can get line level detail
##   (paid amounts for specific procedures, for example).
## * Certain line claims pay at the line:
##     * E, K, F, H, I, L, W, and N
## * Certain line claims pay at the header:
##     * C, J, O
## * Certain header claims pay at the header
##     * B, D, M
## * Pharmacy claims are paid at the header
##     * A
## 
## > 4. ~13% of claim lines with the same TCN that have more than 1 claim line
## >    do not have the same service dates as the associated claim header
## 
## * True.  Line adjudicated claims may have Dates of Service that are not captured
##   in the one DOS field available on the Claim Header.
## * Claim headers contain summary information (earliest first date of service,
##   the latest last date of service, and total payment that is NOT the sum of the
##   line payment (except if you are looking at C, J, and O claims)).
##  */
## /* 
## Include claims with claim type = "A"
## They are pharmacy claims
## 
## > You can get easily get `CLNT_ID` by linking the `CLM_TCN` from the Rx Claim
## > Line data to the `CLM_TCN` in the Claim Header Table.  Every `CLM_TCN` in the
## > Rx line table will have a `CLM_TCN` in the Claims Header Table.  As we
## > discussed on the last call, would recommend staying away from the RX line
## > table.  Use the Claim Header Table with Claim Type = *A* to get Rx
## > information.
##  */
## /* 
## * Batch Doc Type
## * Claim Type
## * Service category
## These map uniquely across claim header and claim line (matched on CLM_TCN).
## (Almost uniquely for Service category, very small percentage of TCNs have non-unique values)
## 
## => Keep the value from the claim line dataset
##  */
## proc sql;
##   create table Work.lookup as
##   select CLNT_ID, dateCoverageBegin, dateCoverageEnd 
##   from Staged.clientSnapshot
##   /* where isSample1 */
##   ;
##   create table Staged.rxClaims as 
##   select
##     coalesce(A.CLNT_ID, B.CLNT_ID) as CLNT_ID,
##     "D" || coalesce(A.CLNT_ID, B.CLNT_ID) as memberID,
##     coalesce(A.CLM_TCN, B.CLM_TCN, C.CLM_TCN) as CLM_TCN,
## /* 
##     The datepart function will return a warning.
##     > NOTE: Invalid (or missing) arguments to the DATEPART function have caused the function to return a missing value.
##     Missing values don't appear to seriously break anything.
##  */
##     datepart(A.SRV_FROM_DT) format=yymmdd10. as dateDispensed,
##     year(calculated dateDispensed) as year,
##     mdy(ceil(month(calculated dateDispensed) / 3) * 3,
##         case ceil(month(calculated dateDispensed) / 3) * 3
##             when  3 then 31
##             when  6 then 30
##             when  9 then 30
##             when 12 then 31
##             else .
##             end,
##         calculated year)
##       format=yymmdd10. as yearEnding,
##     A.BATCH_DOC_TYP_CD format=$char. as batchDocType,
##     coalesce(A.CLM_TYPE_CD, B.CLM_TYPE_CD) format=$char. as claimType,
##     A.BILL_TYPE_CD format=$char. as typeOfBill,
##     A.POC_CD format=$char.,
##     A.COS_CD format=$char. as srvCat,
##     A.CLM_STS_CD as clmstatus,
##     A.PD_AMT as amtPaid,
##     A.ALLOW_CHRG_AMT as amtAllowed,
##     A.BILL_AMT as amtBilled,
##     A.COPAY_AMT as amtCopay,
##     A.MCARE_PD_AMT as amtMedicarePaid,
##     A.TPL_AMT as amtTPL,
##     B.DRUG_PRESC_PROV_ID,
##     B.DRUG_PRESC,
##     B.DRUG_PLAN_ID,
##     C.DRG_THR_CHAR3_CD,
##     C.DRUG_CD as ndc,
##     C.DRUG_GEN_CD_NUM,
##     C.DRUG_NAM,
##     C.PD_QTY_AMT as qtyDispensed,
##     C.SUBM_ING_QTY_AMT,
##     A.prov_bill_id,
##     coalesce(A.isSample1, B.isSample1) as isSample1,
##     coalesce(A.isSample5, B.isSample5) as isSample5
##   from
##     PreSt.claimHeader A
##     inner join PreSt.rxClaimHeader B
##     on (A.CLNT_ID = B.CLNT_ID & A.CLM_TCN = B.CLM_TCN)
##     inner join PreSt.rxClaimLine C
##     on (A.CLM_TCN = C.CLM_TCN)
##     inner join Work.lookup Z
##     on (A.CLNT_ID = Z.CLNT_ID & 
##         (Z.dateCoverageBegin <= datepart(A.SRV_FROM_DT) <= Z.dateCoverageEnd | 
##          Z.dateCoverageBegin <= datepart(B.SRV_FROM_DT) <= Z.dateCoverageEnd))
##   where
##     /* A.isSample1 & */
##     A.CLM_TYPE_CD = "A" & 
##     B.CLM_TYPE_CD = "A" &
##     A.BATCH_DOC_TYP_CD ^in ("E", "F") &
##     A.CLM_STS_CD = "P" &
##     A.PD_AMT ^= 0
##   ;
## quit;
## 
## 
## /* 
## Check sampling indicators
##  */
## proc sql;
##   select
##     isSample1,
##     isSample5,
##     count(*) as countRows
##   from
##     Staged.rxClaims
##   group by
##     isSample1,
##     isSample5
##   ;
## quit;
## 
## 
## /* 
## Make indexes
##  */
## proc datasets library=Staged;
##   modify rxClaims;
##   index create memberID;
##   index create CLM_TCN;
## run;
## 
## 
## /* 
## Make colClasses dataset.
## Output for later use in R.
##  */
## proc contents data=Staged.rxClaims order=varnum out=Work.contents noprint;
## run;
## proc sql;
##   create table Staged.colClasses as
##   select
##     case
##       when type = 2 then "character"
##       when prxmatch("/\$/", format) then "character"
##       when prxmatch("/YYMMDD/", format) then "character"
##       when formatd > 0 then "numeric"
##       else "integer"
##     end as colClass
##   from Work.contents
##   order by
##     varnum
##   ;
## quit;
## 
## 
## /* 
## Export datasets to CSV files for later use in R
##  */
## filename f "&pathData\Staged\rxClaims.csv";
## proc export data=Staged.rxClaims outfile=f dbms=csv replace;
## run;
## filename f "&pathData\Staged\colClasses.csv";
## proc export data=Staged.colClasses outfile=f dbms=csv replace;
## run;
## No errors
## See H:/CHSE/Projects/DataProcessing/ColoradoMedicaid/StagingCode\makeRxClaims.log for details.
##    user  system elapsed 
##    0.02    0.01 1463.35

ISSUE: Need to get daysSupply

We need days supply to code some of the quality measures.

From: Benjamin Chan 
Sent: Monday, June 15, 2015 9:27 AM
To: 'Duke, Jodi Kay'
Subject: RE: days supply field

Oh yes, the package code! Forgot about that. Hmm... that's going to be a little
tricky, I think. I'll need to think about how to implement this. Thanks for
reminding me about the package code.

From: Duke, Jodi Kay [mailto:Jodi.Duke@ucdenver.edu] 
Sent: Saturday, June 13, 2015 1:34 PM
To: Benjamin Chan
Subject: RE: days supply field

Sorry for the delay.  The variable I was thinking of is from the file HCPF told
us not to use --- but it's the "subm_ing_qty_amt" --- but I was also under the
impression that the NDC number included the days of fill.

Example NDC

> For example, the NDC for a 100-count bottle of Prozac 20 mg is 0777-3105-02.
> The first segment of numbers identifies the labeler. In this case, the labeler
> code "00777" is for Dista Products Company, the labeler of Prozac. The second
> segment, the product code, identifies the specific strength, dosage form (i.e,
> capsule, tablet, liquid) and formulation of a drug for a specific
> manufacturer. In our case, "3105" identifies that this dosage form is a
> capsule. The third segment is the package code, and it identifies package
> sizes and types. Our example shows that the package code "02" for this bottle
> of Prozac identifies that 100 capsules are in the bottle. The FDA maintains a
> searchable database of all NDC codes on their website.

7.1 Differences from staging Oregon DMAP and APAC data

Some processing differences from the staging of the Oregon DMAP and APAC data is necessary.

The Oregon DMAP and APAC data was primarily processed using R. A larger chunk of the processing of the Colorado Medicaid data happens in SAS. The migration was mainly influenced by speed/memory considerations. The migrated processes are:

  • Include only claims matched to an included enrollment record
  • Create year variable
  • Create yearEnding variable
  • Fix missing values

7.2 Load helper objects

Load helper objects create by makeHelpers.Rmd.

f <- sprintf("%s\\%s", pathTemp, "helpers.RData")
file.info(f)[c("size", "mtime")]
##                                                              size
## E:\\Share\\Temp\\chanb\\Colorado Medicaid\\helpers.RData 14907116
##                                                                        mtime
## E:\\Share\\Temp\\chanb\\Colorado Medicaid\\helpers.RData 2015-07-17 15:56:58
load(f)

7.3 Read data file

f <- sprintf("%s\\colClasses.csv", pathStaged)
colClasses <- fread(f)
file.remove(f)
## [1] TRUE
f <- sprintf("%s\\rxClaims.csv", pathStaged)
D <- fread(f, colClasses=colClasses[, colClass], na.strings=na.strings, showProgress=FALSE)
# D <- D[isSample1 == TRUE]  # Uncomment this line for testing
D <- D[,
       `:=` (dateDispensed = as.Date(dateDispensed),
             yearEnding = as.Date(yearEnding))]
# str(D)

7.3.1 Check NDC codes

Are NDC codes in the expected 11-digit format?

regex <- "[0-9]{11}"
message(sprintf("%d (%.5f%% or 1 out of %.0f) claims have invalid NDC codes (not 11-digit format)",
                length(D[grep(regex, ndc, invert=TRUE), ndc]),
                length(D[grep(regex, ndc, invert=TRUE), ndc]) / length(D[, ndc]),
                length(D[, ndc]) / length(D[grep(regex, ndc, invert=TRUE), ndc])))
## 542 (0.00003% or 1 out of 28970) claims have invalid NDC codes (not 11-digit format)

If NDC codes are 100% valid, then proceed with merging on FDA variables.

Hold off on doing this. The character columns are long. Save space and do this only when necessary. The code chunk below show the basic procedure to merge FDA variables.

if (length(D[grep(regex, ndc, invert=TRUE), ndc]) == 0) {
  setkey(D, ndc)
  setnames(ndcMaster, "ndcPackageFmt11", "ndc")
  setkey(ndcMaster, ndc)
  D < - merge(D, ndcMaster, all.x=TRUE)
} else {
  warning("NDC codes are not 100% completely valid; there are some NDC codes not in valid format.")
}

7.3.2 Fix some quirks

7.3.3 Quirks that need fixes

Quantities (original variable name: BILL_UOS_QTY). A very small percentage of the quantities are ridiculous.

tails <- c(0, 1E-5, 1E-4, 1E-3, 1E-2)
quantile(D[, qtyDispensed], prob=c(tails, 0.5), na.rm=TRUE)
##       0%   0.001%    0.01%     0.1%       1%      50% 
## -6520423   -12000    -4000     -527     -200       30
quantile(D[, qtyDispensed], prob=c(0.5, 1-rev(tails)), na.rm=TRUE)
##         50%         99%       99.9%      99.99%     99.999%        100% 
##      30.000     400.000    1200.000    7394.725   36267.198 6520423.000

7.3.4 Create bucketID and amtAllowedUnit

For prescription drug claims, the bucketID = ndc.

D <- D[,
       `:=` (bucketID = ndc,
             amtAllowedUnit = amtAllowed / qtyDispensed)]

7.3.5 Generic drug indicator

ISSUE

There is no generic drug indicator on the Colorado HCPF data. Also, it is unclear how to use the DRUG_GEN_CD_NUM field in the data.

The lookup table in the Valid Values.xls spreadsheet shows values like

        VALID_VALUE_SRC_CD VALID_VALUE_CD VALID_VALUE_DSC
     1:                GEN    00450048224           70221
     2:                GEN    00450048235           70221
     3:                GEN    00450048250           70221
     4:                GEN    00450048810           16965
     5:                GEN    00450048815           16965
    ---                                                  
389967:                GEN    00440875430           00870
389968:                GEN    00440875514           00871
389969:                GEN    00440875530           00871
389970:                GEN    00440876091           20831
389971:                GEN    00440876160           20833

The VALID_VALUE_CD column clearly shows 11-digit NDC codes. But it is unclear what the VALID_VALUE_DSC column shows. Also, it is unclear if this table is populated only for generic drugs. (are there 389,891 generic drugs?)

The code chunk below is from Staging_Code13TransformVariables.Rmd. Do not run this chunk. It is only shown to illustrate what we want to end up with.

dtRx$isGeneric <- dtRx[, ind_drug_generic == "Y"]

7.3.6 Sensitive conditions indicator

This is to emulate what we would see in the commercial/APAC claims. Reference: (http://www.oregon.gov/oha/OHPR/RSCH/docs/All_Payer_all_Claims/CHDlogic_06-25-2013.xls).

Download (http://www.oregon.gov/oha/OHPR/RSCH/docs/All_Payer_all_Claims/CHDlogic_06-25-2013.xls).

url <- "http://www.oregon.gov/oha/OHPR/RSCH/docs/All_Payer_all_Claims/CHDlogic_06-25-2013.xls"
f <- tempfile(fileext="xls")
download.file(url, f, mode="wb")
## Warning in download.file(url, f, mode = "wb"): downloaded length 160768 !=
## reported length 160768
require(xlsx)

Create indicator for sensitive conditions.

D <- D[, isSensitiveCondition := FALSE]
D <- D[ndc %in% as.character(read.xlsx(f, 7)[, 1]),
       isSensitiveCondition := TRUE]
checkIndicator(D, "isSensitiveCondition")
##    isSensitiveCondition      N  prop
## 1:                FALSE 160094 99.5%
## 2:                 TRUE    784  0.5%

7.4 Save to RData and Stata datasets

Reset the key variables.

setkey(D, year, memberID)

Remove typeOfBill, first. All rows are NA. This solution does not fix the problem.

D <- D[, typeOfBill := NULL]

Save full datasets.

rxClaims <- D
f <- sprintf("%s\\%s", pathStaged, "rxClaims_Colorado")
metadata <- makeMetadata("makeRxClaims.Rmd")
system.time(save(metadata, rxClaims, file=sprintf("%s.RData", f)))
##    user  system elapsed 
##  384.85    2.34  389.87
system.time(save.dta13(rxClaims, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
##  927.35   40.28  973.01
rbind(file.info(sprintf("%s.RData", f))[c("size", "mtime")],
      file.info(sprintf("%s.dta", f))[c("size", "mtime")])
##                                                                                     size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\rxClaims_Colorado.RData  518266284
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\rxClaims_Colorado.dta   2999021921
##                                                                                             mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\rxClaims_Colorado.RData 2015-07-17 21:37:53
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\rxClaims_Colorado.dta   2015-07-17 21:54:17
# str(rxClaims)

Save 5% test sample datasets.

rxClaims <- D[isSample5 == TRUE]
f <- sprintf("%s\\%s", pathStaged, "rxClaims_ColoradoSample5")
metadata <- makeMetadata("makeRxClaims.Rmd")
system.time(save(metadata, rxClaims, file=sprintf("%s.RData", f)))
##    user  system elapsed 
##   19.74    0.16   20.01
system.time(save.dta13(rxClaims, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
##   45.95    1.82   48.15
rbind(file.info(sprintf("%s.RData", f))[c("size", "mtime")],
      file.info(sprintf("%s.dta", f))[c("size", "mtime")])
##                                                                                           size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\rxClaims_ColoradoSample5.RData  25986172
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\rxClaims_ColoradoSample5.dta   149230678
##                                                                                                    mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\rxClaims_ColoradoSample5.RData 2015-07-17 21:54:49
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\rxClaims_ColoradoSample5.dta   2015-07-17 21:55:48

Clean up.

rm(rxClaims)
gc()
##              used   (Mb) gc trigger    (Mb)   max used    (Mb)
## Ncells   24989677 1334.6   53481193  2856.3   53481193  2856.3
## Vcells 1082369146 8257.9 3194426721 24371.6 4647940320 35461.0

Delete temporary data files.

filenames <- list.files(pathStaged)
filenames <- sprintf("%s\\%s", pathStaged, filenames[grep("^rxClaims\\.((csv))", list.files(pathStaged), ignore.case=TRUE)])
message(sprintf("Deleting file: %s\n", filenames))
## Deleting file: E:\Share\DataRepository\Colorado Medicaid\Staged\rxClaims.csv
file.remove(filenames)
## [1] TRUE

8 ICD-9 diagnosis codes

Read in ICD-9 diagnosis and procedure codes.

In the HCPF system, these data elements are in separate datasets.

A big portion of the processing is done by the SAS script, makeICD9.sas. The output is a CSV file to be read in by R later on in this script.

See Recommendations in TestScripts\checkOtherDiagnosisFile.html.

system.time(callSAS("makeICD9.sas", path=pathScripts))
## /* 
## Set library paths.
## Set options.
##  */
## %let pathData = E:\Share\DataRepository\Colorado Medicaid;
## libname PreSt "&pathData\PreStaged" access=readonly;
## libname Staged "&pathData\Staged";
## options fmtsearch = (Staged);
## options formchar="|----|+|---+=|-/\<>*";
## options ls=132 ps=max;
## 
## 
## /* 
## MAIN QUERY
##  */
## 
## proc sql;
##   create table Work.lookup as
##   select distinct 
##     memberID, 
##     CLM_TCN, 
##     dateFirstSvc, 
##     yearEnding 
##   from 
##     Staged.claims 
##   /* where 
##     isSample1 */
##   union
##   select distinct 
##     memberID, 
##     CLM_TCN, 
##     dateDispensed as dateFirstSvc, 
##     yearEnding 
##   from 
##     Staged.rxClaims 
##   /* where 
##     isSample1 */
##   ;
##   create table Work.diagnosisCodesAllFiles as
##   select CLM_TCN, 1 as SEQ_NUM, ICD_DIAG_1_CD as DIAG_CD, 1 as source from PreSt.claimHeader    where ICD_DIAG_1_CD ^= "" union
##   select CLM_TCN, 1 as SEQ_NUM, ICD_DIAG_1_CD as DIAG_CD, 2 as source from PreSt.claimLine      where ICD_DIAG_1_CD ^= "" union
##   select CLM_TCN, 2 as SEQ_NUM, ICD_DIAG_2_CD as DIAG_CD, 2 as source from PreSt.claimLine      where ICD_DIAG_2_CD ^= "" union
##   select CLM_TCN, 3 as SEQ_NUM, ICD_DIAG_3_CD as DIAG_CD, 2 as source from PreSt.claimLine      where ICD_DIAG_3_CD ^= "" union
##   select CLM_TCN, 4 as SEQ_NUM, ICD_DIAG_4_CD as DIAG_CD, 2 as source from PreSt.claimLine      where ICD_DIAG_4_CD ^= "" union
##   select CLM_TCN,      SEQ_NUM, DIAG_CD       as DIAG_CD, 3 as source from PreSt.otherDiagnosis where DIAG_CD       ^= "" 
##   ;
##   alter table Work.diagnosisCodesAllFiles
##     modify DIAG_CD format=$10. label=""
##     modify SEQ_NUM label=""
##   ;
##   select 
##     case source
##       when 1 then "Claim header file"
##       when 2 then "Claim line file"
##       when 3 then "Other diagnosis file"
##       else ""
##       end as source,
##     count(*) format=comma12.0 as countRows, 
##     count(*) / (select count(*) from Work.diagnosisCodesAllFiles) format=percent10.2 as propRows
##   from
##     Work.diagnosisCodesAllFiles
##   group by
##     source
##   ;
##   select
##     case source
##       when 1 then "Claim header file"
##       when 2 then "Claim line file"
##       when 3 then "Other diagnosis file"
##       else ""
##       end as source,
##     SEQ_NUM, 
##     count(*) format=comma12.0 as countRows, 
##     count(*) / (select count(*) from Work.diagnosisCodesAllFiles) format=percent10.2 as propRows
##   from
##     Work.diagnosisCodesAllFiles
##   group by
##     source,
##     SEQ_NUM
##   ;
##   create table Staged.diagnosisCodes as 
##   select
##     A.memberID,
##     A.CLM_TCN,
##     A.dateFirstSvc,
##     A.yearEnding,
##     prxchange("s/\.//", -1, C.DIAG_CD) format=$char10. as icd9cm,
##     C.SEQ_NUM,
##     C.SEQ_NUM = 1 length=3 as isPrincipalCode,
##     case C.source
##       when 1 then "Claim header file"
##       when 2 then "Claim line file"
##       when 3 then "Other diagnosis file"
##       else ""
##       end as source,
##     B.age,
##     B.gender,
##     B.isSample1,
##     B.isSample5
##   from
##     Work.lookup A
##     inner join Staged.clientSnapshot B
##     on (A.memberID = B.memberID & B.dateCoverageBegin <= A.dateFirstSvc <= B.dateCoverageEnd)
##     inner join Work.diagnosisCodesAllFiles C
##     on (A.CLM_TCN = C.CLM_TCN)
##   ;
##   create table Staged.procedureCodes as 
##   select
##     A.memberID,
##     A.CLM_TCN,
##     A.dateFirstSvc,
##     A.yearEnding,
##     prxchange("s/\.//", -1, C.OTHER_PROC_CODE) format=$char7. as icd9pcs,
##     C.SEQ_NUM,
##     C.SEQ_NUM = 1 length=3 as isPrincipalCode,
##     B.isSample1,
##     B.isSample5
##   from
##     Work.lookup A
##     inner join Staged.clientSnapshot B
##     on (A.memberID = B.memberID & B.dateCoverageBegin <= A.dateFirstSvc <= B.dateCoverageEnd)
##     inner join PreSt.otherProcedure C
##     on (A.CLM_TCN = C.CLM_TCN)
##   ;
## quit;
## 
## 
## /* 
## Check sampling indicators
##  */
## proc sql;
##   select
##     "Staged.diagnosisCodes" as dataset,
##     isSample1,
##     isSample5,
##     count(*) as countRows
##   from
##     Staged.diagnosisCodes
##   group by
##     dataset,
##     isSample1,
##     isSample5
##   ;
##   select
##     "Staged.procedureCodes" as dataset,
##     isSample1,
##     isSample5,
##     count(*) as countRows
##   from
##     Staged.procedureCodes
##   group by
##     dataset,
##     isSample1,
##     isSample5
##   ;
## quit;
## 
## 
## /* 
## Make indexes
##  */
## proc datasets library=Staged;
##   modify diagnosisCodes;
##   index create memberID;
##   index create CLM_TCN;
## run;
##   modify procedureCodes;
##   index create memberID;
##   index create CLM_TCN;
## run;
## 
## 
## /* 
## Make colClasses dataset.
## Output for later use in R.
##  */
## proc contents data=Staged.diagnosisCodes order=varnum out=Work.contentsDx noprint;
## run;
## proc contents data=Staged.procedureCodes order=varnum out=Work.contentsPx noprint;
## run;
## proc sql;
##   create table Work.colClassesDx as
##   select
##     case
##       when type = 2 then "character"
##       when prxmatch("/\$/", format) then "character"
##       when prxmatch("/YYMMDD/", format) then "character"
##       when formatd > 0 then "numeric"
##       else "integer"
##     end as colClass
##   from Work.contentsDx
##   order by
##     varnum
##   ;
##   create table Work.colClassesPx as
##   select
##     case
##       when type = 2 then "character"
##       when prxmatch("/\$/", format) then "character"
##       when prxmatch("/YYMMDD/", format) then "character"
##       when formatd > 0 then "numeric"
##       else "integer"
##     end as colClass
##   from Work.contentsPx
##   order by
##     varnum
##   ;
## quit;
## 
## 
## /* 
## Export datasets to CSV files for later use in R
##  */
## filename f "&pathData\Staged\diagnosisCodes.csv";
## proc export data=Staged.diagnosisCodes outfile=f dbms=csv replace;
## run;
## filename f "&pathData\Staged\procedureCodes.csv";
## proc export data=Staged.procedureCodes outfile=f dbms=csv replace;
## run;
## filename f "&pathData\Staged\colClassesDx.csv";
## proc export data=Work.colClassesDx outfile=f dbms=csv replace;
## run;
## filename f "&pathData\Staged\colClassesPx.csv";
## proc export data=Work.colClassesPx outfile=f dbms=csv replace;
## run;
## No errors
## See H:/CHSE/Projects/DataProcessing/ColoradoMedicaid/StagingCode\makeICD9.log for details.
##    user  system elapsed 
##    0.00    0.01 3303.43

8.1 Note on the compatibility with the Oregon data

The Oregon Medicaid data from DMAP contains only 4 ICD-9 diagnosis codes and 3 ICD-9 procedure codes. The Oregon APAC data contains 13 ICD-9 diagnosis and procedure codes, each. We used only the commercial claims from the Oregon APAC data for the CCO project.

In order to keep the Oregon commercial data from APAC compatible with the Oregon Medicaid data from DMAP, we only used 4 ICD-9 diagnosis codes and 3 ICD-9 procedure codes from the Oregon APAC data.

When creating the data files from the Colorado data, the data files created in this section, diagnosisCodes.* and procedureCodes.*, will contain all the codes from the

  • Claim header file (only the principal)
  • Claim line file (up to 4 deep)
  • Other diagnosis file (up to 25 deep)

However, when processing the claims (e.g., isVisit indicators) and for comorbidities (e.g., CDPS), only 4 ICD-9 diagnosis codes and 3 ICD-9 procedure codes will be used.

8.2 Read diagnosis code data file

f <- sprintf("%s\\colClassesDx.csv", pathStaged)
colClasses <- fread(f)
file.remove(f)
## [1] TRUE
f <- sprintf("%s\\diagnosisCodes.csv", pathStaged)
D <- fread(f, colClasses=colClasses[, colClass], na.strings=na.strings, showProgress=FALSE)
# D <- D[isSample1 == TRUE]  # Uncomment this line for testing
D <- D[,
       `:=` (dateFirstSvc = as.Date(dateFirstSvc),
             yearEnding = as.Date(yearEnding))]
# str(D)

8.2.1 Remove the decimal point

This should be redundant since it is done with the prxchange function in makeICD9.sas. Keep it in, just in case.

Before Check that there are decimal points in icd9cm.

D[, .N, list(hasDecimal = grepl("\\.", icd9cm))]
##    hasDecimal        N
## 1:      FALSE 76793825

Remove decimal points.

D <- D[, icd9cm := gsub("\\.", "", icd9cm)]

After Check that there are decimal points in icd9cm.

D[, .N, list(hasDecimal = grepl("\\.", icd9cm))]
##    hasDecimal        N
## 1:      FALSE 76793825

8.2.2 Check validity of ICD-9 codes

I don’t want to move this early in the data processiong stream (i.e., to makeICD9.sas). The reason is we might want to further investigate these invalid codes. If we do, then we can go back to the SAS data file created by makeICD9.sas.

## SAS data file E:\Share\DataRepository\Colorado Medicaid\Staged\diagnosisCodes.csv
  • Recode ICD-9 diagnosis codes that do not have a leading character between 0-9, E, or V, followed by 2-4 digits to NA.

Before Check prevalence of invalid codes.

validCode <- "^[0-9EV][0-9]{2,4}$"
D[, .N, list(isValid = grepl(validCode, icd9cm))]
##    isValid        N
## 1:    TRUE 76786622
## 2:   FALSE     7203
D[grep(validCode, icd9cm, invert=TRUE), .N, list(isValid = grepl(validCode, icd9cm), icd9cm)]
##      isValid icd9cm  N
##   1:   FALSE     70  2
##   2:   FALSE  0V481 16
##   3:   FALSE   0V61  1
##   4:   FALSE   C441  2
##   5:   FALSE 741 90  2
##  ---                  
## 237:   FALSE   COLL  1
## 238:   FALSE   VO61  2
## 239:   FALSE 71946L  1
## 240:   FALSE 99559Y  2
## 241:   FALSE E81201  1

Recode to NA.

D <- D[grep(validCode, icd9cm, invert=TRUE), icd9cm := NA]

After Check prevalence of invalid codes.

D[, .N, list(isValid = grepl(validCode, icd9cm))]
##    isValid        N
## 1:    TRUE 76786622
## 2:   FALSE     7203
D[grep(validCode, icd9cm, invert=TRUE), .N, list(isValid = grepl(validCode, icd9cm), icd9cm)]
##    isValid icd9cm    N
## 1:   FALSE     NA 7203

8.2.3 Rename

Dx <- D

8.3 Read procedure code data file

f <- sprintf("%s\\colClassesPx.csv", pathStaged)
colClasses <- fread(f)
file.remove(f)
## [1] TRUE
f <- sprintf("%s\\procedureCodes.csv", pathStaged)
D <- fread(f, colClasses=colClasses[, colClass], na.strings=na.strings, showProgress=FALSE)
# D <- D[isSample1 == TRUE]  # Uncomment this line for testing
D <- D[,
       `:=` (dateFirstSvc = as.Date(dateFirstSvc),
             yearEnding = as.Date(yearEnding))]
# str(D)

8.3.1 Remove the decimal point

This should be redundant since it is done with the prxchange function in makeICD9.sas. Keep it in, just in case.

Before Check that there are decimal points in icd9pcs.

D[, .N, list(hasDecimal = grepl("\\.", icd9pcs))]
##    hasDecimal      N
## 1:      FALSE 472596

Remove decimal points.

D <- D[, icd9pcs := gsub("\\.", "", icd9pcs)]

After Check that there are decimal points in icd9pcs.

D[, .N, list(hasDecimal = grepl("\\.", icd9pcs))]
##    hasDecimal      N
## 1:      FALSE 472596

8.3.2 Check validity of ICD-9 codes

I don’t want to move this early in the data processiong stream (i.e., to makeICD9.sas). The reason is we might want to further investigate these invalid codes. If we do, then we can go back to the SAS data file created by makeICD9.sas.

## SAS data file E:\Share\DataRepository\Colorado Medicaid\Staged\procedureCodes.csv
  • Recode ICD-9 procedure codes that do not have 3-4 digits to NA.

Before Check prevalence of invalid codes.

validCode <- "^[0-9]{3,4}$"
D[, .N, list(isValid = grepl(validCode, icd9pcs))]
##    isValid      N
## 1:    TRUE 472376
## 2:   FALSE    220
D[grep(validCode, icd9pcs, invert=TRUE), .N, list(isValid = grepl(validCode, icd9pcs), icd9pcs)]
##    isValid icd9pcs   N
## 1:   FALSE   G0154  35
## 2:   FALSE   G0152  17
## 3:   FALSE   G0151 144
## 4:   FALSE   G0156   4
## 5:   FALSE      11   2
## 6:   FALSE      21   3
## 7:   FALSE   V5869   2
## 8:   FALSE      51  13

Recode to NA.

D <- D[grep(validCode, icd9pcs, invert=TRUE), icd9pcs := NA]

After Check prevalence of invalid codes.

D[, .N, list(isValid = grepl(validCode, icd9pcs))]
##    isValid      N
## 1:    TRUE 472376
## 2:   FALSE    220
D[grep(validCode, icd9pcs, invert=TRUE), .N, list(isValid = grepl(validCode, icd9pcs), icd9pcs)]
##    isValid icd9pcs   N
## 1:   FALSE      NA 220

8.3.3 Rename

Px <- D

8.4 Save to RData and Stata datasets

See Note on the compatibility with the Oregon data section above.

Save full datasets.

diagnosisCodes <- Dx
f <- sprintf("%s\\%s", pathStaged, "diagnosisCodes")
metadata <- makeMetadata("makeICD9.Rmd")
system.time(save(metadata, diagnosisCodes, file=sprintf("%s.RData", f)))
##    user  system elapsed 
##  521.48    2.37  525.73
system.time(save.dta13(diagnosisCodes, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
## 1456.10   70.17 1532.87
procedureCodes <- Px
f <- sprintf("%s\\%s", pathStaged, "procedureCodes")
metadata <- makeMetadata("makeICD9.Rmd")
system.time(save(metadata, procedureCodes, file=sprintf("%s.RData", f)))
##    user  system elapsed 
##    3.03    0.05    3.08
system.time(save.dta13(procedureCodes, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
##    5.29    0.20    5.55
rbind(file.info(sprintf("%s.RData", f))[c("size", "mtime")],
      file.info(sprintf("%s.dta", f))[c("size", "mtime")])
##                                                                                size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\procedureCodes.RData  3674570
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\procedureCodes.dta   20796586
##                                                                                          mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\procedureCodes.RData 2015-07-18 00:23:42
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\procedureCodes.dta   2015-07-18 00:23:56
# str(diagnosisCodes)
# str(procedureCodes)

Save 5% test sample datasets.

diagnosisCodes <- Dx[isSample5 == TRUE]
f <- sprintf("%s\\%s", pathStaged, "diagnosisCodesSample5")
metadata <- makeMetadata("makeICD9.Rmd")
system.time(save(metadata, diagnosisCodes, file=sprintf("%s.RData", f)))
##    user  system elapsed 
##   25.25    0.07   25.43
system.time(save.dta13(diagnosisCodes, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
##   72.91    3.46   76.70
procedureCodes <- Px[isSample5 == TRUE]
f <- sprintf("%s\\%s", pathStaged, "procedureCodesSample5")
metadata <- makeMetadata("makeICD9.Rmd")
system.time(save(metadata, procedureCodes, file=sprintf("%s.RData", f)))
##    user  system elapsed 
##    0.14    0.02    0.15
system.time(save.dta13(procedureCodes, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
##    0.28    0.01    0.30
rbind(file.info(sprintf("%s.RData", f))[c("size", "mtime")],
      file.info(sprintf("%s.dta", f))[c("size", "mtime")])
##                                                                                      size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\procedureCodesSample5.RData  192410
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\procedureCodesSample5.dta   1018674
##                                                                                                 mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\procedureCodesSample5.RData 2015-07-18 00:26:07
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\procedureCodesSample5.dta   2015-07-18 00:26:17

Clean up.

rm(diagnosisCodes, procedureCodes, D)
gc()
##              used    (Mb) gc trigger    (Mb)   max used    (Mb)
## Ncells   28340847  1513.6   53481193  2856.3   53481193  2856.3
## Vcells 1446693770 11037.4 3354228057 25590.8 4647940320 35461.0

Delete temporary data files.

filenames <- list.files(pathStaged)
filenames <- sprintf("%s\\%s",
                     pathStaged,
                     filenames[grep("Codes\\.((csv))",
                                    list.files(pathStaged),
                                    ignore.case=TRUE)])
message(sprintf("Deleting file: %s\n", filenames))
## Deleting file: E:\Share\DataRepository\Colorado Medicaid\Staged\diagnosisCodes.csv
## Deleting file: E:\Share\DataRepository\Colorado Medicaid\Staged\procedureCodes.csv
file.remove(filenames)
## [1] TRUE TRUE

9 Make indicators

makeICD9.Rmd needs to be run after makeClaims.Rmd and makeRxClaims.Rmd. So the creation of the indicators that depend on icd9cm# and icd9pcs# variables need to be done separately from the code in makeClaims.Rmd and makeRxClaims.Rmd.

This program makes these indicators.

9.1 Load helper objects

Load helper objects create by makeHelpers.Rmd.

f <- sprintf("%s\\%s", pathTemp, "helpers.RData")
file.info(f)[c("size", "mtime")]
##                                                              size
## E:\\Share\\Temp\\chanb\\Colorado Medicaid\\helpers.RData 14907116
##                                                                        mtime
## E:\\Share\\Temp\\chanb\\Colorado Medicaid\\helpers.RData 2015-07-17 15:56:58
load(f, verbose=TRUE)
## Loading objects:
##   metadata
##   objNames
##   validValues
##   lBatchDocType
##   lClaimType
##   codeBetos
##   facBetos
##   dfHedisValueSets
##   dfBH
##   regexPCP
##   regexMH
##   lCodesAcuteInpatient
##   lCodesNonacuteInpatient
##   lCodesIPUExclusionsDRG
##   lCodesMaternityDRG
##   lCodesSurgeryDRG
##   lCodesMedicineDRG
##   lCodesNewbornsDRG
##   lCodesMaternityDiagnosis
##   lCodesMaternity
##   lCodesSurgery
##   lCodesObservation
##   lCodesED
##   lCodesEDProcedureCode
##   lCodesEDPOS
##   lCodesOutpatient
##   lCodesAmbulatoryOutpatient
##   lCodesDetox
##   lCodesPregnancy
##   lCodesOutpatientExpanded
##   lCodesMentalIllness
##   lCodesMentalHealthDiagnosis
##   lCodesBHGeneral
##   lCodesSPMI
##   lCodesHCCPsychiatric
##   ndcMaster
##   checkIndicator

9.2 Load claims data

Load the claims data created by makeClaims.Rmd.

f <- sprintf("%s\\%s", pathStaged, "claims_Colorado.RData")
file.info(f)[c("size", "mtime")]
##                                                                                   size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_Colorado.RData 1227834506
##                                                                                           mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_Colorado.RData 2015-07-17 19:31:10
system.time(load(f, verbose=TRUE))
## Loading objects:
##   metadata
##   claims
##    user  system elapsed 
##  664.79    6.21  673.82
D <- claims
rm(claims)

9.3 ICD-9 codes

Read ICD-9 diagnosis code data. Only read the first 4 diagnosis codes. See Note on the compatibility with the Oregon data section.

f <- sprintf("%s\\diagnosisCodes.RData", pathStaged)
file.info(f)[c("size", "mtime")]
##                                                                                 size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\diagnosisCodes.RData 463993770
##                                                                                          mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\diagnosisCodes.RData 2015-07-17 23:57:49
load(file=f, verbose=TRUE)
## Loading objects:
##   metadata
##   diagnosisCodes
diagnosisCodes0 <- diagnosisCodes[SEQ_NUM <= 4, list(memberID, CLM_TCN, icd9cm, SEQ_NUM)]
setkey(diagnosisCodes0, memberID, CLM_TCN, SEQ_NUM)
diagnosisCodes <- unique(diagnosisCodes0)
message(sprintf("Number of duplicate ICD-9 diagnosis codes removed:\n%s out of %s (%.2f%%)",
                format(nrow(diagnosisCodes0) - nrow(diagnosisCodes), big.mark=","),
                format(nrow(diagnosisCodes0), big.mark=","),
                100 * ((nrow(diagnosisCodes0) - nrow(diagnosisCodes)) / nrow(diagnosisCodes0))))
## Number of duplicate ICD-9 diagnosis codes removed:
## 32,889,155 out of 74,513,755 (44.14%)
dx1 <- diagnosisCodes[SEQ_NUM == 1]
dx2 <- diagnosisCodes[SEQ_NUM == 2]
dx3 <- diagnosisCodes[SEQ_NUM == 3]
dx4 <- diagnosisCodes[SEQ_NUM == 4]
setnames(dx1, "icd9cm", "icd9cm1")
setnames(dx2, "icd9cm", "icd9cm2")
setnames(dx3, "icd9cm", "icd9cm3")
setnames(dx4, "icd9cm", "icd9cm4")
keyvar <- c("memberID", "CLM_TCN")
setkeyv(dx1, keyvar)
setkeyv(dx2, keyvar)
setkeyv(dx3, keyvar)
setkeyv(dx4, keyvar)
dx <- merge(dx1[, SEQ_NUM := NULL], dx2[, SEQ_NUM := NULL], all.x=TRUE)
dx <- merge(dx                    , dx3[, SEQ_NUM := NULL], all.x=TRUE)
dx <- merge(dx                    , dx4[, SEQ_NUM := NULL], all.x=TRUE)
rm(diagnosisCodes0, diagnosisCodes, dx1, dx2, dx3, dx4)
gc()
##              used    (Mb) gc trigger    (Mb)   max used    (Mb)
## Ncells   31352775  1674.5   53481193  2856.3   53481193  2856.3
## Vcells 3824887763 29181.6 5558967878 42411.6 5542306234 42284.5

Read ICD-9 procedure code data. Only read the first 3 diagnosis codes. See Note on the compatibility with the Oregon data section.

f <- sprintf("%s\\procedureCodes.RData", pathStaged)
file.info(f)[c("size", "mtime")]
##                                                                               size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\procedureCodes.RData 3674570
##                                                                                          mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\procedureCodes.RData 2015-07-18 00:23:42
load(file=f, verbose=TRUE)
## Loading objects:
##   metadata
##   procedureCodes
procedureCodes0 <- procedureCodes[SEQ_NUM <= 3, list(memberID, CLM_TCN, icd9pcs, SEQ_NUM)]
setkey(procedureCodes0, memberID, CLM_TCN, SEQ_NUM)
procedureCodes <- unique(procedureCodes0)
message(sprintf("Number of duplicate ICD-9 procedure codes removed:\n%s out of %s (%.2f%%)",
                format(nrow(procedureCodes0) - nrow(procedureCodes), big.mark=","),
                format(nrow(procedureCodes0), big.mark=","),
                100 * ((nrow(procedureCodes0) - nrow(procedureCodes)) / nrow(procedureCodes0))))
## Number of duplicate ICD-9 procedure codes removed:
## 15,530 out of 421,280 (3.69%)
px1 <- procedureCodes[SEQ_NUM == 1]
px2 <- procedureCodes[SEQ_NUM == 2]
px3 <- procedureCodes[SEQ_NUM == 3]
setnames(px1, "icd9pcs", "icd9pcs1")
setnames(px2, "icd9pcs", "icd9pcs2")
setnames(px3, "icd9pcs", "icd9pcs3")
keyvar <- c("memberID", "CLM_TCN")
setkeyv(px1, keyvar)
setkeyv(px2, keyvar)
setkeyv(px3, keyvar)
px <- merge(px1[, SEQ_NUM := NULL], px2[, SEQ_NUM := NULL], all.x=TRUE)
px <- merge(px                    , px3[, SEQ_NUM := NULL], all.x=TRUE)
rm(procedureCodes0, procedureCodes, px1, px2, px3)
gc()
##              used    (Mb) gc trigger    (Mb)   max used    (Mb)
## Ncells   31352758  1674.5   53481193  2856.3   53481193  2856.3
## Vcells 3826094348 29190.8 5558967878 42411.6 5542306234 42284.5

Merge ICD-9 diagnosis and procedure codes.

icd9 <- merge(dx, px, all=TRUE)
rm(dx, px)

9.4 Merge ICD-9 codes to claims

n0 <- nrow(D)
names0 <- names(D)
setkeyv(D, key(icd9))
D <- merge(D, icd9, all.x=TRUE)
message(sprintf("Number of rows BEFORE merge: %d\nNumber of rows AFTER merge: %d\nAre they the same? %s",
                n0,
                nrow(D),
                identical(n0, nrow(D))))
## Number of rows BEFORE merge: 60023284
## Number of rows AFTER merge: 60023284
## Are they the same? TRUE
message(sprintf("Added variable: %s\n",
                setdiff(names0, names(D))))
## 
if (identical(n0, nrow(D))) {
  rm(icd9, n0)
}

9.5 Create visit indicators

Inpatient indicator. Do not use isVisitAcuteInpatient; it is junk. See page 292, Inpatient Utilization–General Hospital/Acute Care (IPU), of the HEDIS 2014 documentation. Use the intermediate indicators

  • isVisitInpatient; does the claim have either
  • Type of bill beginning with 11 or 12,
  • Place of service = 21, or
  • Claim type of Inpatient
  • IPU Exclusions MS-DRG Value Set
  • Maternity MS-DRG Value Set
  • Surgery MS-DRG Value Set
  • Medicine MS-DRG Value Set
  • Newborns/Neonates MS-DRG Value Set
  • Maternity Diagnosis Value Set
  • Maternity Value Set
  • Surgery Value Set

Recode NA to FALSE. (NAs are assigned if variables used in the calculations are NA)

D <- D[,
       `:=` (isVisitInpatient = 
               (grepl("^1[12]", typeOfBill) | 
                  pos == 21 | 
                  grepl("INPATIENT", claimType)) & 
               !(drg %in% lCodesIPUExclusionsDRG))]
D <- D[is.na(isVisitInpatient), isVisitInpatient := FALSE]
D <- D[,
       `:=` (isVisitIPMaternity = 
               isVisitInpatient == TRUE &
               ((drg %in% lCodesMaternityDRG$drg) |
                  (icd9cm1 %in% lCodesMaternityDiagnosis$icd9cm | 
                     icd9cm2 %in% lCodesMaternityDiagnosis$icd9cm | 
                     icd9cm3 %in% lCodesMaternityDiagnosis$icd9cm | 
                     icd9cm4 %in% lCodesMaternityDiagnosis$icd9cm) |
                  (ubRev %in% lCodesMaternity$ubRev | 
                     typeOfBill %in% lCodesMaternity$typeOfBill)),
             isVisitIPSurgery = 
               isVisitInpatient == TRUE & 
               ((drg %in% lCodesSurgeryDRG$drg) 
                | (ubRev %in% lCodesSurgery$ubRev)))]
D <- D[is.na(isVisitIPMaternity), isVisitIPMaternity := FALSE]
D <- D[is.na(isVisitIPSurgery), isVisitIPSurgery := FALSE]
D <- D[,
       `:=` (isVisitIPMedicine = 
               isVisitInpatient == TRUE & 
               ((drg %in% lCodesMedicineDRG$drg) | 
                  (isVisitIPMaternity != TRUE & 
                     isVisitIPSurgery != TRUE)),
             isVisitIPNewborns = 
               isVisitInpatient == TRUE & 
               drg %in% lCodesNewbornsDRG$drg)]
D <- D[is.na(isVisitIPMedicine), isVisitIPMedicine := FALSE]
D <- D[is.na(isVisitIPNewborns), isVisitIPNewborns := FALSE]
checkIndicator(D, "isVisitInpatient"  )
##    isVisitInpatient      N  prop
## 1:            FALSE 590157 97.0%
## 2:             TRUE  18194  3.0%
checkIndicator(D, "isVisitIPMaternity")
##    isVisitIPMaternity      N  prop
## 1:              FALSE 604538 99.4%
## 2:               TRUE   3813  0.6%
checkIndicator(D, "isVisitIPSurgery"  )
##    isVisitIPSurgery      N  prop
## 1:            FALSE 608036 99.9%
## 2:             TRUE    315  0.1%
checkIndicator(D, "isVisitIPMedicine" )
##    isVisitIPMedicine      N  prop
## 1:             FALSE 593164 97.5%
## 2:              TRUE  15187  2.5%
checkIndicator(D, "isVisitIPNewborns" )
##    isVisitIPNewborns      N   prop
## 1:             FALSE 608350 100.0%
## 2:              TRUE      1   0.0%

For inpatient visits, calculate length of stay (LOS).

D <- D[, los := ifelse(isVisitInpatient == TRUE, dateLastSvc - dateFirstSvc + 1, NA)]
summary(D[isSample1 == TRUE, los])
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##     1.0     1.0     1.0     1.5     1.0   177.0  590157

Visit indicators.

D <- D[,
       `:=` (isVisitAcuteInpatient = 
               cpt %in% lCodesAcuteInpatient$cpt | 
               ubRev %in% lCodesAcuteInpatient$ubRev,
             isVisitNonacuteInpatient = 
               cpt %in% lCodesNonacuteInpatient$cpt | 
               ubRev %in% lCodesNonacuteInpatient$ubRev,
             isVisitObservation = 
               cpt %in% lCodesObservation$cpt,
             isVisitED = 
               (cpt %in% lCodesED$cpt | ubRev %in% lCodesED$ubRev) | 
               (cpt %in% lCodesEDProcedureCode$cpt & pos %in% lCodesEDPOS$pos),
             isVisitOutpatient = 
               cpt %in% lCodesOutpatient$cpt | 
               ubRev %in% lCodesOutpatient$ubRev,
             isVisitAmbulatoryOutpatient = 
               cpt %in% lCodesAmbulatoryOutpatient$cpt | 
               ubRev %in% lCodesAmbulatoryOutpatient$ubRev,
             isVisitOutpatientExpanded = 
               cpt %in% lCodesOutpatientExpanded$cpt | 
               (icd9cm1 %in% lCodesOutpatientExpanded$icd9cm | 
                  icd9cm2 %in% lCodesOutpatientExpanded$icd9cm | 
                  icd9cm3 %in% lCodesOutpatientExpanded$icd9cm | 
                  icd9cm4 %in% lCodesOutpatientExpanded$icd9cm) | 
               ubRev %in% lCodesOutpatientExpanded$ubRev,
             isVisitDetox = 
               cpt %in% lCodesDetox$cpt | 
               (icd9pcs1 %in% lCodesDetox$icd9pcs | 
                  icd9pcs2 %in% lCodesDetox$icd9pcs | 
                  icd9pcs3 %in% lCodesDetox$icd9pcs) | 
               ubRev %in% lCodesDetox$ubRev,
             isVisitPCP = grepl(regexPCP, cpt),
             isVisitPregnancy = 
               (icd9cm1 %in% lCodesPregnancy$icd9cm | 
                  icd9cm2 %in% lCodesPregnancy$icd9cm | 
                  icd9cm3 %in% lCodesPregnancy$icd9cm | 
                  icd9cm4 %in% lCodesPregnancy$icd9cm))]
checkIndicator(D, "isVisitAcuteInpatient"      )
##    isVisitAcuteInpatient      N  prop
## 1:                 FALSE 601734 98.9%
## 2:                  TRUE   6617  1.1%
checkIndicator(D, "isVisitNonacuteInpatient"   )
##    isVisitNonacuteInpatient      N  prop
## 1:                    FALSE 607763 99.9%
## 2:                     TRUE    588  0.1%
checkIndicator(D, "isVisitObservation"         )
##    isVisitObservation      N  prop
## 1:              FALSE 607855 99.9%
## 2:               TRUE    496  0.1%
checkIndicator(D, "isVisitED"                  )
##    isVisitED      N  prop
## 1:     FALSE 569803 93.7%
## 2:      TRUE  38548  6.3%
checkIndicator(D, "isVisitOutpatient"          )
##    isVisitOutpatient      N  prop
## 1:             FALSE 505838 83.1%
## 2:              TRUE 102513 16.9%
checkIndicator(D, "isVisitAmbulatoryOutpatient")
##    isVisitAmbulatoryOutpatient      N  prop
## 1:                       FALSE 504069 82.9%
## 2:                        TRUE 104282 17.1%
checkIndicator(D, "isVisitOutpatientExpanded"  )
##    isVisitOutpatientExpanded      N  prop
## 1:                     FALSE 490745 80.7%
## 2:                      TRUE 117606 19.3%
checkIndicator(D, "isVisitDetox"               )
##    isVisitDetox      N   prop
## 1:        FALSE 608351 100.0%
checkIndicator(D, "isVisitPCP"                 )
##    isVisitPCP      N  prop
## 1:      FALSE 522887 86.0%
## 2:       TRUE  85464 14.0%
checkIndicator(D, "isVisitPregnancy"           )
##    isVisitPregnancy      N  prop
## 1:            FALSE 558241 91.8%
## 2:             TRUE  50110  8.2%

9.6 Check if the client had at least one pregnancy visit in each quarter.

Pregnancy visit is defined using the HEDIS value set for Pregnancy. See lCodesPregnancy in makeHelpers.Rmd*. This is used downstream to populate the cohort variable.

lookupPreg <- D[, list(isAnyVisitPregnancy = any(isVisitPregnancy)), list(memberID, yearEnding)]
setkey(lookupPreg, memberID, yearEnding)
f <- sprintf("%s\\%s", pathTemp, "lookupPreg.RData")
metadata <- makeMetadata("makeIndicators.Rmd")
system.time(save(metadata, lookupPreg, file=f))
##    user  system elapsed 
##    7.24    0.07    7.33
file.info(f)[c("size", "mtime")]
##                                                                size
## E:\\Share\\Temp\\chanb\\Colorado Medicaid\\lookupPreg.RData 5053102
##                                                                           mtime
## E:\\Share\\Temp\\chanb\\Colorado Medicaid\\lookupPreg.RData 2015-07-18 01:06:15
rm(lookupPreg)

9.7 Behavioral health indicators.

D <- D[,
       `:=` (isDiagBHGeneral = 
               icd9cm1 %in% lCodesBHGeneral$icd9cm | 
               icd9cm2 %in% lCodesBHGeneral$icd9cm | 
               icd9cm3 %in% lCodesBHGeneral$icd9cm | 
               icd9cm4 %in% lCodesBHGeneral$icd9cm,
             isDiagSPMI = 
               icd9cm1 %in% lCodesSPMI$icd9cm | 
               icd9cm2 %in% lCodesSPMI$icd9cm | 
               icd9cm3 %in% lCodesSPMI$icd9cm | 
               icd9cm4 %in% lCodesSPMI$icd9cm,
             isDiagHCCPsychiatric = 
               icd9cm1 %in% lCodesHCCPsychiatric$icd9cm | 
               icd9cm2 %in% lCodesHCCPsychiatric$icd9cm | 
               icd9cm3 %in% lCodesHCCPsychiatric$icd9cm | 
               icd9cm4 %in% lCodesHCCPsychiatric$icd9cm,
             isDiagMentalIllness = 
               icd9cm1 %in% lCodesMentalIllness$icd9cm | 
               icd9cm2 %in% lCodesMentalIllness$icd9cm | 
               icd9cm3 %in% lCodesMentalIllness$icd9cm | 
               icd9cm4 %in% lCodesMentalIllness$icd9cm,
             isDiagMentalHealthDiagnosis = 
               icd9cm1 %in% lCodesMentalHealthDiagnosis$icd9cm | 
               icd9cm2 %in% lCodesMentalHealthDiagnosis$icd9cm | 
               icd9cm3 %in% lCodesMentalHealthDiagnosis$icd9cm | 
               icd9cm4 %in% lCodesMentalHealthDiagnosis$icd9cm)]
checkIndicator(D, "isDiagBHGeneral"            )
##    isDiagBHGeneral      N  prop
## 1:           FALSE 565755 93.0%
## 2:            TRUE  42596  7.0%
checkIndicator(D, "isDiagSPMI"                 )
##    isDiagSPMI      N  prop
## 1:      FALSE 601670 98.9%
## 2:       TRUE   6681  1.1%
checkIndicator(D, "isDiagHCCPsychiatric"       )
##    isDiagHCCPsychiatric      N  prop
## 1:                FALSE 603130 99.1%
## 2:                 TRUE   5221  0.9%
checkIndicator(D, "isDiagMentalIllness"        )
##    isDiagMentalIllness      N  prop
## 1:               FALSE 588878 96.8%
## 2:                TRUE  19473  3.2%
checkIndicator(D, "isDiagMentalHealthDiagnosis")
##    isDiagMentalHealthDiagnosis      N  prop
## 1:                       FALSE 565573 93.0%
## 2:                        TRUE  42778  7.0%

For mental health visit, use the Behavioral Health General Definition. Ref: Goldman, 2006 and McConnell, 2012.

D <- D[, isVisitMentalHealth := grepl(regexMH, cpt) & isDiagBHGeneral == TRUE]
checkIndicator(D, "isVisitMentalHealth")
##    isVisitMentalHealth      N  prop
## 1:               FALSE 596171 98.0%
## 2:                TRUE  12180  2.0%

Other indicators.

D <- D[, isTypeProfessional := claimType == "PRACTITIONER/PHYSICIAN"]
D <- D[is.na(isTypeProfessional), isTypeProfessional := FALSE]
checkIndicator(D, "isTypeProfessional")
##    isTypeProfessional      N  prop
## 1:              FALSE 414778 68.2%
## 2:               TRUE 193573 31.8%

9.8 Create indicator for claims that are acute inpatient visits through the ED.

ISSUE Incorporate new isVisitInpatientThruED and isVisitEDPriorToInpatient logic

From: John McConnell  
Sent: Friday, April 11, 2014 12:48 PM  
To: Benjamin Chan  
Subject: Inpatient Admission through ED  
 
Hey Ben  
I took a look at the data with Hyunjee and it seems like we could separate out
inpatient admissions into two categories (ED vs. elected) using this algorithm.
 
1)  Pick observations with revenue code=0450-459 or 981 and check the service
start date & then, for that person_id,  **Use `isVisitED` instead**

2)  Check whether they had an inpatient claim with the same service start date
 
It seems like that would require two reads of the data but then (in theory)
could create a flag for any inpatient visit that could then be called an "ED
admitted" inpatient visit.

**The issue below should be fixed now (2014-10-09)**

From: John McConnell  
Sent: Saturday, September 20, 2014 10:16 AM  
To: Benjamin Chan  
Subject: future data request  

Here's a request for a future fix on the data. This one could be a little
tricky. These inpatient episodes are a little tough.

Here's the issue

The variable isVisitInpatientThruED correctly flags inpatient visits on the day
of admission but then is 0 for the remainder of the stay. But it would be great
if it flagged it for the whole stay, so we could create a measure of spending
that is attributable to the whole stay (and separate by whether the stay
initiated electively or through the ED).

On the following example, this patient was admitted through the ED on 3-Mar-11
and then stayed in the hospital through 8-Mar-11. Ideally (I think) it would be
nice if isVisitInpatientThruED was `1` for the whole stay, instead of on the day
of admission. Then it would be easy to create variables that captured all
spending for that stay.

Let me know if that makes sense or if you want to discuss.

I tried to think of an easy fix but couldn't come up with one.
isVisitInpatient isVisitInpatientThruED memberID dateFirstSvc dateLastSvc claimType drg icd9pcs1 amtAllowed
1 1 ### 3-Mar-YY 3-Mar-YY B NA NA 6.96
1 1 ### 3-Mar-YY 3-Mar-YY M NA NA 0
1 1 ### 3-Mar-YY 3-Mar-YY M NA NA 8.62
1 1 ### 3-Mar-YY 8-Mar-YY I 92 9904 8947.5
1 0 ### 4-Mar-YY 4-Mar-YY M NA NA 0
1 0 ### 4-Mar-YY 4-Mar-YY M NA NA 6.96
1 0 ### 5-Mar-YY 5-Mar-YY M NA NA 29.21
1 0 ### 6-Mar-YY 6-Mar-YY M NA NA 6.96
1 0 ### 6-Mar-YY 6-Mar-YY M NA NA 29.21
1 0 ### 7-Mar-YY 7-Mar-YY M NA NA 0
1 0 ### 8-Mar-YY 8-Mar-YY M NA NA 0
setkey(D, memberID, dateFirstSvc, dateLastSvc)
EDVisits <- unique(D[isVisitED == TRUE, list(memberID, dateFirstSvc, dateLastSvc, isVisitED)])
IPVisits <- unique(D[isVisitInpatient == TRUE, list(memberID, dateFirstSvc, dateLastSvc, isVisitInpatient)])
setkey(EDVisits, memberID, dateFirstSvc, dateLastSvc)
setkeyv(IPVisits, key(EDVisits))
SameDay <- merge(EDVisits, IPVisits)
SameDay <- SameDay[, isLinkedToEDVisit := TRUE]
setkey(IPVisits, memberID, dateFirstSvc)
setkeyv(SameDay, key(IPVisits))
IPVisitsLinked <- merge(IPVisits,
                        SameDay[, list(memberID, dateFirstSvc, isLinkedToEDVisit)])
setkey(IPVisits, memberID)
setkeyv(IPVisitsLinked, key(IPVisits))
IPVisitsLinked <- merge(IPVisits,
                        IPVisitsLinked[, list(memberID, dateFirstSvc, dateLastSvc)],
                        allow.cartesian=TRUE)
rm(EDVisits, IPVisits, SameDay)
IPVisitsLinked <- IPVisitsLinked[dateFirstSvc.y <= dateFirstSvc.x & dateLastSvc.x <= dateLastSvc.y]
IPVisitsLinked <- IPVisitsLinked[,
                                 `:=` (dateFirstSvc = dateFirstSvc.x,
                                       dateLastSvc = dateLastSvc.x,
                                       dateFirstSvc.x = NULL,
                                       dateLastSvc.x  = NULL,
                                       dateFirstSvc.y = NULL,
                                       dateLastSvc.y  = NULL,
                                       isVisitInpatientThruED = TRUE)]
IPVisitsLinked <- unique(IPVisitsLinked, by=NULL)
setkey(IPVisitsLinked, memberID, dateFirstSvc, dateLastSvc, isVisitInpatient)
setkeyv(D, key(IPVisitsLinked))
D <- merge(D, IPVisitsLinked, all.x=TRUE)
D <- D[is.na(isVisitInpatientThruED), isVisitInpatientThruED := FALSE]
D[,
  .N,
  list(isVisitInpatient,
       isVisitInpatientThruED)][, prop := sprintf("%.1f%%", N / sum(N) * 100)][order(isVisitInpatient, isVisitInpatientThruED)]
##    isVisitInpatient isVisitInpatientThruED        N  prop
## 1:            FALSE                  FALSE 58341475 97.2%
## 2:             TRUE                  FALSE  1386916  2.3%
## 3:             TRUE                   TRUE   294893  0.5%
rm(IPVisitsLinked)

9.9 Create indicator for sensitive conditions.

This is to emulate what we would see in the commercial/APAC claims. Reference: (http://www.oregon.gov/oha/OHPR/RSCH/docs/All_Payer_all_Claims/CHDlogic_06-25-2013.xls).

Download (http://www.oregon.gov/oha/OHPR/RSCH/docs/All_Payer_all_Claims/CHDlogic_06-25-2013.xls).

url <- "http://www.oregon.gov/oha/OHPR/RSCH/docs/All_Payer_all_Claims/CHDlogic_06-25-2013.xls"
f <- tempfile(fileext="xls")
download.file(url, f, mode="wb")
## Warning in download.file(url, f, mode = "wb"): downloaded length 160768 !=
## reported length 160768
require(xlsx)

Create indicator for sensitive conditions as a combination of the flags.

Remove the flag using npiBilling, npiPerforming and npiPlan. These are specific to Oregon and cannot be generalized to Colorado.

D <- D[, isSensitiveCondition := FALSE]
D <- D[pos %in% c(55, 57) |
         ubRev %in% as.character(read.xlsx(f, 2)[, 1]) |
         cpt %in% as.character(read.xlsx(f, 3)[, 1]) |
         (cptModifier1 %in% as.character(read.xlsx(f, 4)[, 1]) | 
            cptModifier2 %in% as.character(read.xlsx(f, 4)[, 1])) |
         (icd9pcs1 %in% as.character(read.xlsx(f, 5)[, 1]) | 
            icd9pcs2 %in% as.character(read.xlsx(f, 5)[, 1]) | 
            icd9pcs3 %in% as.character(read.xlsx(f, 5)[, 1])) |
         (icd9cm1 %in% as.character(read.xlsx(f, 6)[, 1]) | 
            icd9cm2 %in% as.character(read.xlsx(f, 6)[, 1])) |
         (icd9cm3 %in% as.character(read.xlsx(f, 6)[, 1]) | 
            icd9cm4 %in% as.character(read.xlsx(f, 6)[, 1])),
       isSensitiveCondition := TRUE]
checkIndicator(D, "isSensitiveCondition")
##    isSensitiveCondition      N  prop
## 1:                FALSE 607493 99.9%
## 2:                 TRUE    858  0.1%

9.10 Save to RData and Stata datasets

Reset the key variables.

setkey(D, year, memberID)

Save full datasets.

claims <- D
f <- sprintf("%s\\%s", pathStaged, "claims_Colorado")
metadata <- makeMetadata("makeIndicators.Rmd")
system.time(save(metadata, claims, file=sprintf("%s.RData", f)))
##    user  system elapsed 
## 1664.36    7.44 1679.41
system.time(save.dta13(claims, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
## 5332.16  211.71 5570.24
rbind(file.info(sprintf("%s.RData", f))[c("size", "mtime")],
      file.info(sprintf("%s.dta", f))[c("size", "mtime")])
##                                                                                    size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_Colorado.RData  1342253504
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_Colorado.dta   15065859246
##                                                                                           mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_Colorado.RData 2015-07-18 01:43:28
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_Colorado.dta   2015-07-18 03:16:37
# str(claims)

Save 5% test sample datasets.

claims <- D[isSample5 == TRUE]
f <- sprintf("%s\\%s", pathStaged, "claims_ColoradoSample5")
metadata <- makeMetadata("makeIndicators.Rmd")
system.time(save(metadata, claims, file=sprintf("%s.RData", f)))
##    user  system elapsed 
##   83.49    0.26   84.30
system.time(save.dta13(claims, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
##  258.48   10.78  270.63
rbind(file.info(sprintf("%s.RData", f))[c("size", "mtime")],
      file.info(sprintf("%s.dta", f))[c("size", "mtime")])
##                                                                                         size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_ColoradoSample5.RData  66941398
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_ColoradoSample5.dta   742101962
##                                                                                                  mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_ColoradoSample5.RData 2015-07-18 03:18:29
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_ColoradoSample5.dta   2015-07-18 03:23:14

Clean up.

rm(claims)
gc()
##              used    (Mb)  gc trigger    (Mb)   max used    (Mb)
## Ncells   31354655  1674.6    53481193  2856.3   53481193  2856.3
## Vcells 4878263193 37218.2 10641158216 81185.6 8330056232 63553.3

Delete temporary data files.

filenames <- list.files(pathStaged)
filenames <- sprintf("%s\\%s", pathStaged, filenames[grep("^claims\\.((csv))", list.files(pathStaged), ignore.case=TRUE)])
message(sprintf("Deleting file: %s\n", filenames))
## 
file.remove(filenames)
## logical(0)

10 Cohort variable

Create the following client-level cohorts:

This needs to happen AFTER the object lookupPreg is created.

10.1 Load datasets

Load datasets created earlier in the sequence.

f <- sprintf("%s\\%s", pathStaged, "mem_detail_Colorado.RData")
load(f, verbose=TRUE)
## Loading objects:
##   metadata
##   mem_detail_Colorado
f <- sprintf("%s\\%s", pathTemp, "lookupPreg.RData")
load(f, verbose=TRUE)
## Loading objects:
##   metadata
##   lookupPreg

Merge the datasets.

if (key(mem_detail_Colorado)[1] == "memberID" & key(mem_detail_Colorado)[2] == "yearEnding") {
  setkey(mem_detail_Colorado, memberID, yearEnding)
}
if (key(lookupPreg)[1] == "memberID" & key(lookupPreg)[2] == "yearEnding") {
  setkey(lookupPreg, memberID, yearEnding)
}
D <- merge(mem_detail_Colorado, lookupPreg, all.x=TRUE)

Check the merge.

D[, .N, isAnyVisitPregnancy]
##    isAnyVisitPregnancy       N
## 1:               FALSE 1193411
## 2:                  NA 1504416
## 3:                TRUE   50757
D <- D[is.na(isAnyVisitPregnancy), isAnyVisitPregnancy := FALSE]
D[, .N, isAnyVisitPregnancy]
##    isAnyVisitPregnancy       N
## 1:               FALSE 2697827
## 2:                TRUE   50757
rm(lookupPreg)

10.2 Populate

Populate the cohort variable for pregnant women. isChildBearingAge already accounts for gender == "F". Check the minimum and maximum ages for each cohort.

x <- sprintf("**%d to %d**",
             D[isChildBearingAge == TRUE, min(age)],
             D[isChildBearingAge == TRUE, max(age)])
  • Non-pregnant adults
    • Minumum age should be 19
  • Pregnant women
    • Age range should be narrower than 13 to 66 (the child-bearing age range)
  • Children age 1 year or older
    • Age range should be 1 to 18
  • Children age less than 1 year
    • Age range should be 0 to 0
D <- D[, cohort := ifelse(isChildBearingAge == TRUE & isAnyVisitPregnancy == TRUE, 2, NA)]
D <- D[, cohort := ifelse(is.na(cohort), ifelse(age == 0, 4, ifelse(age < 19, 3, 1)), cohort)]
labels <- c("Non-pregnant adults", "Pregnant women", "Children age 1 year or older", "Children age less than 1 year")
D <- D[, cohort := factor(cohort, label=labels)]
D[,
  list(n = length(age), minAge = min(age), maxAge = max(age)), 
  list(cohort, gender, isChildBearingAge, isAnyVisitPregnancy)][order(cohort, gender, isChildBearingAge, isAnyVisitPregnancy)]
##                            cohort gender isChildBearingAge
##  1:           Non-pregnant adults      F             FALSE
##  2:           Non-pregnant adults      F              TRUE
##  3:           Non-pregnant adults      M             FALSE
##  4:           Non-pregnant adults      M             FALSE
##  5:                Pregnant women      F              TRUE
##  6:  Children age 1 year or older      F             FALSE
##  7:  Children age 1 year or older      F             FALSE
##  8:  Children age 1 year or older      F              TRUE
##  9:  Children age 1 year or older      M             FALSE
## 10:  Children age 1 year or older      M             FALSE
## 11:  Children age 1 year or older      U             FALSE
## 12: Children age less than 1 year      F             FALSE
## 13: Children age less than 1 year      F             FALSE
## 14: Children age less than 1 year      M             FALSE
##     isAnyVisitPregnancy       n minAge maxAge
##  1:               FALSE       5     67     67
##  2:               FALSE  467077     19     66
##  3:               FALSE  171804     19     68
##  4:                TRUE      15     20     32
##  5:                TRUE   50637     13     59
##  6:               FALSE  566812      1     12
##  7:                TRUE     101      1     12
##  8:               FALSE  449396     13     18
##  9:               FALSE 1042592      1     18
## 10:                TRUE       3     11     18
## 11:               FALSE       2     14     16
## 12:               FALSE      69      0      0
## 13:                TRUE       1      0      0
## 14:               FALSE      70      0      0

10.3 Save to RData and Stata datasets

message(sprintf("Added the following variables to mem_detail_Colorado: %s\n",
                setdiff(names(D), names(mem_detail_Colorado))))
## Added the following variables to mem_detail_Colorado: isAnyVisitPregnancy
## Added the following variables to mem_detail_Colorado: cohort

Ignore save.dta13 warning. See this issue.

Save full datasets.

mem_detail_Colorado <- D
f <- sprintf("%s\\%s", pathStaged, "mem_detail_Colorado")
metadata <- makeMetadata("makeCohortVariable.Rmd")
system.time(save(metadata, mem_detail_Colorado, file=sprintf("%s.RData", f)))
##    user  system elapsed 
##   55.97    0.20   56.56
system.time(save.dta13(mem_detail_Colorado, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
##  202.97   12.03  216.20
rbind(file.info(sprintf("%s.RData", f))[c("size", "mtime")],
      file.info(sprintf("%s.dta", f))[c("size", "mtime")])
##                                                                                      size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_Colorado.RData  22752509
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_Colorado.dta   929032554
##                                                                                               mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_Colorado.RData 2015-07-18 03:25:33
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_Colorado.dta   2015-07-18 03:29:18
# str(mem_detail_Colorado)

Save 5% test sample datasets.

mem_detail_Colorado <- D[isSample5 == TRUE]
f <- sprintf("%s\\%s", pathStaged, "mem_detail_ColoradoSample5")
metadata <- makeMetadata("makeCohortVariable.Rmd")
system.time(save(metadata, mem_detail_Colorado, file=sprintf("%s.RData", f)))
##    user  system elapsed 
##    2.79    0.00    2.83
system.time(save.dta13(mem_detail_Colorado, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
##    9.30    0.52    9.92
rbind(file.info(sprintf("%s.RData", f))[c("size", "mtime")],
      file.info(sprintf("%s.dta", f))[c("size", "mtime")])
##                                                                                            size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_ColoradoSample5.RData   880388
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_ColoradoSample5.dta   46270478
##                                                                                                      mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_ColoradoSample5.RData 2015-07-18 03:29:30
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_ColoradoSample5.dta   2015-07-18 03:29:48

Clean up.

rm(mem_detail_Colorado)
gc()
##              used    (Mb) gc trigger    (Mb)   max used    (Mb)
## Ncells   28343971  1513.8   53481193  2856.3   53481193  2856.3
## Vcells 1563518783 11928.8 4358618404 33253.7 8330056232 63553.3

11 Run CDPS

CDPS is the Chronic Illness and Disability Payment System diagnostic classification system. Link is here.

The Chronic Illness and Disability Payment System (CDPS) is a diagnostic classification system that Medicaid programs can use to make health-based capitated payments for TANF and disabled Medicaid beneficiaries. The CDPS code is provided under license and free of charge to qualified public agencies, educational institutions, and researchers.

We are using CDPS Version 5.4.

A big portion of the processing is done by the SAS script, runCDPS.sas. The output is a CSV file to be read in by R later on in this script.

system.time(callSAS("runCDPS.sas", path=pathScripts))
## /* =============================================================================
## Set library paths.
## ============================================================================= */
## %let pathData = E:\Share\DataRepository\Colorado Medicaid;
## libname PreSt "&pathData\PreStaged" access=readonly;
## libname Staged "&pathData\Staged";
## libname libCDPS "E:\Share\LookupTablesAndCrosswalks\CDPS\CDPS_5.4\CDPS Code\CDPS 5.4" access=readonly;
## libname libMRX  "E:\Share\LookupTablesAndCrosswalks\CDPS\CDPS_5.4\CDPS Code\MRX 5.4" access=readonly;
## %let pathCDPS = CDPS 5.4\CDPS Code\CDPS 5.4;
## %let pathMRX  = CDPS 5.4\CDPS Code\MRX 5.4;
## 
## 
## /* =============================================================================
## Set options.
## ============================================================================= */
## options fmtsearch = (Staged);
## options formchar="|----|+|---+=|-/\<>*";
## options ls=132 ps=max;
## 
## 
## /* =============================================================================
## Include cdps01.sas and mrx01.sas
## ============================================================================= */
## filename f "&pathCDPS\cdps01.sas";
## %include f / source2;
## filename f "&pathMRX\mrx01.sas";
## %include f / source2;
## 
## 
## /* =============================================================================
## Create helper dataset
## ============================================================================= */
## proc sql;
##   create table Work.yearEnding as
##   select 
##     monotonic() as i,
##      datepart(A.Snapshot_End_Dt) format=yymmdd10. as dateEnd,
##  mdy(month(calculated dateEnd), day(calculated dateEnd), year(calculated dateEnd) - 1) + 1 format=yymmdd10. as dateBeg
##   from
##      PreSt.SnapshotPeriodDefinition A
##   where
##      month(calculated dateEnd) in (3, 6, 9, 12)
##   ;
##   select * from Work.yearEnding
##   ;
##   create view Work.nPeriods as
##   select count(*) as nPeriods from Work.yearEnding
##   ;
## quit;
## data _null_;
##   set Work.nPeriods;
##   call symput ("nPeriods", put(nPeriods, 2.));
## run;
## %put macro variable nPeriods = &nPeriods;
## 
## 
## /*==============================================================================
## Loop through 12-month lookbacks.
## ==============================================================================*/
## %macro loop;
##  %do per = 1 %to &nPeriods;
##      proc sql;
##      /*======================================================================
##      Create step1 dataset from claims
## 
##      * This program expects a temporary input SAS data file called "step1" ;
##      *       (usually claims data) with these variables:                   ;
##      *          RECIPNO:  Character              (Recipient ID number)     ;
##      *          DIAG_1:    Character, length 5   (ICD-9 code, no decimal)  ;
##      *      and DIAG_2:    Character, length 5   (ICD-9 code, no decimal)  ;
##      *    The file "step1" MUST be sorted by RECIPNO,                      ;
##      *       and will probably have more than one record per person.       ;
##      *                                                                     ;
##      * This program summarizes all diagnoses for each RECIPNO,             ;
##      *      checking two fields (DIAG_1 and DIAG_2) for ICD-9 codes.       ;
##      *                                                                     ;
##      * If you have more than two diagnosis codes, you will need to create  ;
##      *       a file with additional records for these diagnoses.           ;
##      *    For example:                                                     ;
##      *          data inelig(keep=recipno diag_1 diag_2);
##      *            set diagdata(keep=recipno diag_1-diag_4);
##      *            output inelig;                        
##      *            diag_1=diag_3; 
##      *            diag_2=diag_4;            
##      *            output inelig;                      
##      *           run;                                
## 
##      The SAS datasets retain the decimal point;
##      (should get fixed after commit ee30b94def535117f453034b446a7c8a48f03dc4).
##      Need to remove the decimal.
## 
##      Also need to get clever with the structuring of the dataset.
##      The source dataset is narrow and has up to 25 diagnosis codes per claim.
##      Need to create separate datasets for odd/even numbered diagnosis codes, each.
##      ======================================================================*/
##          create table Work.iteration as
##          select dateBeg, dateEnd from Work.yearEnding where i = &per
##          ;
##          create view Work.diagnosisCodes as
##          select yearEnding, memberID, CLM_TCN, icd9cm, SEQ_NUM 
##          from Staged.diagnosisCodes 
##          where SEQ_NUM <= 4
##          ;
##          create table Work.claimsOdd as
##          select
##              B.memberID as recipno,
##              B.CLM_TCN,
##              prxchange("s/\.//", -1, B.icd9cm) as diag_1,
##              B.SEQ_NUM,
##              round(B.SEQ_NUM, 2) - 1 as roundSeqNum
##          from
##              Work.iteration A
##              inner join (select * from Work.diagnosisCodes where mod(SEQ_NUM, 2) = 1) B
##              on (A.dateBeg <= B.yearEnding <= A.dateEnd)
##          ;
##          create table Work.claimsEven as
##          select
##              B.memberID as recipno,
##              B.CLM_TCN,
##              prxchange("s/\.//", -1, B.icd9cm) as diag_2,
##              B.SEQ_NUM,
##              round(B.SEQ_NUM, 2) - 1 as roundSeqNum
##          from
##              Work.iteration A
##              inner join (select * from Work.diagnosisCodes where mod(SEQ_NUM, 2) = 0) B
##              on (A.dateBeg <= B.yearEnding <= A.dateEnd)
##          ;
##      /*======================================================================
##      Then, merge.
##      Sort and get rid of duplicate rows.
##      ======================================================================*/
##          create table Work.step1 as
##          select distinct
##              A.recipno,
##              A.diag_1,
##              B.diag_2
##          from
##              Work.claimsOdd A
##              left join Work.claimsEven B
##              on (A.recipno = B.recipno & A.CLM_TCN = B.CLM_TCN & A.roundSeqNum = B.roundSeqNum)
##          order by
##              A.recipno,
##              A.diag_1,
##              B.diag_2
##          ;
##      quit;
##      /*======================================================================
##      Create inelig dataset
## 
##      * This program expects a temporary input SAS data file called "inelig";
##      *       (eligibility data) with these variables:                      ;
##      *           RECIPNO:  Character      (Recipient ID number)            ;
##      *           AGE:      Numeric        (Age in years)                   ;
##      *       and MALE:     Numeric        (Indicator 0/1 for male gender)  ;
##      *    The file "inelig" MUST be sorted by RECIPNO,                     ;
##      *       and MUST have one record per person.                          ;
##      ======================================================================*/
##      proc sql;
##          create table Work.inelig as
##          select distinct
##              B.memberID as recipno,
##              B.age,
##              B.gender
##          from
##              Work.iteration A
##              inner join (select yearEnding, memberID, age, gender
##                          from Staged.diagnosisCodes) B
##              on (A.dateBeg <= B.yearEnding <= A.dateEnd)
##          order by
##              B.memberID,
##              B.age,
##              B.gender
##          ;
##      quit;
##      data Work.inelig;
##          set Work.inelig;
##          by recipno age gender;
##          male = (gender = "M");
##          if last.recipno then output;
##          keep recipno age male;
##      run;
##      /*======================================================================
##      Make sure there are no duplicates
##      ======================================================================*/
##      proc sort data=Work.inelig nodup;
##          by recipno age male;
##      run;
##      /*======================================================================
##      Call macro cdps
## 
##      Do not run cdps with parameters DA or DC.
##      Per Peter's instructions.
##      ======================================================================*/
##      %cdps(AA);
##      data Work.cdpsAdults;
##          set Work.step2 (where = (age > 18));
##      run;
##      %cdps(AC);
##      data Work.cdpsChildren;
##          set Work.step2 (where = (. < age <= 18));
##      run;
##      /*======================================================================
##      Create step1 dataset from rx
## 
##      * This program expects a temporary input SAS data file called "step1" ;
##      *       (usually claims data) with these variables:                   ;
##      *           RECIPNO:  Character             (Recipient ID number)     ;
##      *       and NDC:      Character, length 11  (NDC code)                ;
##      *    The file "step1" MUST be sorted by RECIPNO,                      ;
##      *       and will probably have more than one record per person.       ;
## 
##      Keep rows with NDC codes in the valid 11-digit format.
##      ======================================================================*/
##      proc sql;
##          create table Work.step1 as
##          select distinct
##              B.memberID as recipno,
##              B.ndc
##          from
##              Work.iteration A
##              inner join (select yearEnding, memberID, ndc
##                          from Staged.rxClaims) B
##              on (A.dateBeg <= B.yearEnding <= A.dateEnd)
##          where
##              prxmatch("/[0-9]{11}/", B.ndc) > 0
##          order by
##              B.memberID,
##              B.ndc
##          ;
##      quit;
##      /*======================================================================
##      Add an aid variable to the inelig dataset.
##      the mrx02 macros require it.
## 
##      * This program expects a temporary input SAS data file called "inelig";
##      *       (eligibility data) with these variables:                      ;
##      *           RECIPNO:  Character      (Recipient ID number)            ;
##      *           AGE:      Numeric        (Age in years)                   ;
##      *           MALE:     Numeric        (Indicator 0/1 for male gender)  ;
##      *           AID:      Character      (Aid category)                   ;
##      ======================================================================*/
##      data Work.inelig;
##          set Work.inelig;
##          if age > 18 then aid = "AA";
##          else if . < age <= 18 then aid = "AC";
##      run;
##      /*======================================================================
##      Call macro mrx
##      ======================================================================*/
##      %mrx;
##      data Work.mrx;
##          set Work.step2;
##      run;
##      /*======================================================================
##      Merge CDPS and MRX datasets.
##      Then stack the adults and the children.
##      This is the set of CDPS indicators for iteration I.
##      Note that it is in library libWork.
##      ======================================================================*/
##      proc sql;
##          create table Work.cdpsIndicators as
##          select
##              Z.dateEnd informat=yymmdd10. format=yymmdd10. as yearEnding,
##              coalesce(A.recipno, B.recipno) as memberID,
##              coalesce(A.a_15_24m, B.a_15_24m) as a_15_24m,
##              coalesce(A.a_15_24f, B.a_15_24f) as a_15_24f,
##              coalesce(A.a_25_44m, B.a_25_44m) as a_25_44m,
##              coalesce(A.a_25_44f, B.a_25_44f) as a_25_44f,
##              coalesce(A.a_45_64m, B.a_45_64m) as a_45_64m,
##              coalesce(A.a_45_64f, B.a_45_64f) as a_45_64f,
##              coalesce(A.a_65    , B.a_65    ) as a_65    ,
##              carvh, carm, carl, carel, psyh, psym, psyml, psyl, skcm, skcl,
##              skcvl, cnsh, cnsm, cnsl, pulvh, pulh, pulm, pull, gih, gim, gil,
##              dia1h, dia1m, dia2m, dia2l, sknh, sknl, sknvl, reneh, renvh,
##              renm, renl, subl, subvl, canvh, canh, canm, canl, ddm, ddl,
##              genel, meth, metm, metvl, prgcmp, prginc, eyel, eyevl, cerl,
##              aidsh, infh, hivm, infm, infl, hemeh, hemvh, hemm, heml, mrx1,
##              mrx2, mrx3, mrx4, mrx5, mrx6, mrx7, mrx8, mrx9, mrx10, mrx11,
##              mrx12, mrx13, mrx14, mrx15, mrx16, mrx17, mrx18, mrx19, mrx20, 
##              mrx21, mrx22, mrx23, mrx24, mrx25, mrx26, mrx27, mrx28, mrx29, 
##              mrx30, mrx31, mrx32, mrx33, mrx34, mrx35, mrx36, mrx37, mrx38, 
##              mrx39, mrx40, mrx41, mrx42, mrx43, mrx44, mrx45
##          from
##              Work.iteration Z, 
##              Work.cdpsAdults A
##              inner join Work.mrx B on (A.recipno = B.recipno)
##          outer union corr
##          select
##              Z.dateEnd informat=yymmdd10. format=yymmdd10. as yearEnding,
##              coalesce(A.recipno, B.recipno) as memberID,
##              coalesce(A.a_15_24m, B.a_15_24m) as a_15_24m,
##              coalesce(A.a_15_24f, B.a_15_24f) as a_15_24f,
##              coalesce(A.a_25_44m, B.a_25_44m) as a_25_44m,
##              coalesce(A.a_25_44f, B.a_25_44f) as a_25_44f,
##              coalesce(A.a_45_64m, B.a_45_64m) as a_45_64m,
##              coalesce(A.a_45_64f, B.a_45_64f) as a_45_64f,
##              coalesce(A.a_65    , B.a_65    ) as a_65    ,
##              carvh, carm, carl, carel, psyh, psym, psyml, psyl, skcm, skcl,
##              skcvl, cnsh, cnsm, cnsl, pulvh, pulh, pulm, pull, gih, gim, gil,
##              dia1h, dia1m, dia2m, dia2l, sknh, sknl, sknvl, reneh, renvh,
##              renm, renl, subl, subvl, canvh, canh, canm, canl, ddm, ddl,
##              genel, meth, metm, metvl, prgcmp, prginc, eyel, eyevl, cerl,
##              aidsh, infh, hivm, infm, infl, hemeh, hemvh, hemm, heml, mrx1,
##              mrx2, mrx3, mrx4, mrx5, mrx6, mrx7, mrx8, mrx9, mrx10, mrx11,
##              mrx12, mrx13, mrx14, mrx15, mrx16, mrx17, mrx18, mrx19, mrx20, 
##              mrx21, mrx22, mrx23, mrx24, mrx25, mrx26, mrx27, mrx28, mrx29, 
##              mrx30, mrx31, mrx32, mrx33, mrx34, mrx35, mrx36, mrx37, mrx38, 
##              mrx39, mrx40, mrx41, mrx42, mrx43, mrx44, mrx45
##          from 
##              Work.iteration Z,
##              Work.cdpsChildren A
##              inner join Work.mrx B on (A.recipno = B.recipno)
##          ;
##      quit;
##      /*======================================================================
##      Initialize the full dataset when &per = 1.s
##      Otherwise, stack the full dataset with the dataset in library libWork.
##      ======================================================================*/
##      data Staged.cdpsIndicators;
##      %if &per = 1 %then %do;
##          set Work.cdpsIndicators;
##      %end;
##      %else %do;
##          set Staged.cdpsIndicators Work.cdpsIndicators;
##      %end;
##      run;
##      /*======================================================================
##      Clean up working datasets
##      ======================================================================*/
##      proc datasets library=Work;
##          delete claimsOdd claimsEven iteration step1 inelig step2 cdpsAdults cdpsChildren mrx cdpsIndicators;
##          delete diagind who;
##      run;
##  %end;
## %mend loop;
## 
## %loop;
## 
## 
## /*======================================================================
## Clean up working datasets
## ======================================================================*/
## proc datasets library=Work;
##  delete yearEnding nPeriods;
## run;
## 
## 
## /*==============================================================================
## Check the final dataset.
## ==============================================================================*/
## proc sql;
##  create table Work.cdpsIndicatorsSummary as
##  select
##      yearEnding,
##      count(distinct memberID) as nDistinctMembers,
##      sum(a_15_24m) as a_15_24m,
##      sum(a_15_24f) as a_15_24f,
##      sum(a_25_44m) as a_25_44m,
##      sum(a_25_44f) as a_25_44f,
##      sum(a_45_64m) as a_45_64m,
##      sum(a_45_64f) as a_45_64f,
##      sum(a_65    ) as a_65    ,
##      sum(carvh ) as carvh , 
##      sum(carm  ) as carm  , 
##      sum(carl  ) as carl  , 
##      sum(carel ) as carel , 
##      sum(psyh  ) as psyh  , 
##      sum(psym  ) as psym  , 
##      sum(psyml ) as psyml , 
##      sum(psyl  ) as psyl  , 
##      sum(skcm  ) as skcm  , 
##      sum(skcl  ) as skcl  ,
##      sum(skcvl ) as skcvl , 
##      sum(cnsh  ) as cnsh  , 
##      sum(cnsm  ) as cnsm  , 
##      sum(cnsl  ) as cnsl  , 
##      sum(pulvh ) as pulvh , 
##      sum(pulh  ) as pulh  , 
##      sum(pulm  ) as pulm  , 
##      sum(pull  ) as pull  , 
##      sum(gih   ) as gih   , 
##      sum(gim   ) as gim   , 
##      sum(gil   ) as gil   ,
##      sum(dia1h ) as dia1h , 
##      sum(dia1m ) as dia1m , 
##      sum(dia2m ) as dia2m , 
##      sum(dia2l ) as dia2l , 
##      sum(sknh  ) as sknh  , 
##      sum(sknl  ) as sknl  , 
##      sum(sknvl ) as sknvl , 
##      sum(reneh ) as reneh , 
##      sum(renvh ) as renvh ,
##      sum(renm  ) as renm  , 
##      sum(renl  ) as renl  , 
##      sum(subl  ) as subl  , 
##      sum(subvl ) as subvl , 
##      sum(canvh ) as canvh , 
##      sum(canh  ) as canh  , 
##      sum(canm  ) as canm  , 
##      sum(canl  ) as canl  , 
##      sum(ddm   ) as ddm   , 
##      sum(ddl   ) as ddl   ,
##      sum(genel ) as genel , 
##      sum(meth  ) as meth  , 
##      sum(metm  ) as metm  , 
##      sum(metvl ) as metvl , 
##      sum(prgcmp) as prgcmp, 
##      sum(prginc) as prginc, 
##      sum(eyel  ) as eyel  , 
##      sum(eyevl ) as eyevl , 
##      sum(cerl  ) as cerl  ,
##      sum(aidsh ) as aidsh , 
##      sum(infh  ) as infh  , 
##      sum(hivm  ) as hivm  , 
##      sum(infm  ) as infm  , 
##      sum(infl  ) as infl  , 
##      sum(hemeh ) as hemeh , 
##      sum(hemvh ) as hemvh , 
##      sum(hemm  ) as hemm  , 
##      sum(heml  ) as heml  , 
##      sum(mrx1  ) as mrx1  ,
##      sum(mrx2  ) as mrx2  , 
##      sum(mrx3  ) as mrx3  , 
##      sum(mrx4  ) as mrx4  , 
##      sum(mrx5  ) as mrx5  , 
##      sum(mrx6  ) as mrx6  , 
##      sum(mrx7  ) as mrx7  , 
##      sum(mrx8  ) as mrx8  , 
##      sum(mrx9  ) as mrx9  , 
##      sum(mrx10 ) as mrx10 , 
##      sum(mrx11 ) as mrx11 ,
##      sum(mrx12 ) as mrx12 , 
##      sum(mrx13 ) as mrx13 , 
##      sum(mrx14 ) as mrx14 , 
##      sum(mrx15 ) as mrx15 , 
##      sum(mrx16 ) as mrx16 , 
##      sum(mrx17 ) as mrx17 , 
##      sum(mrx18 ) as mrx18 , 
##      sum(mrx19 ) as mrx19 , 
##      sum(mrx20 ) as mrx20 , 
##      sum(mrx21 ) as mrx21 , 
##      sum(mrx22 ) as mrx22 , 
##      sum(mrx23 ) as mrx23 , 
##      sum(mrx24 ) as mrx24 , 
##      sum(mrx25 ) as mrx25 , 
##      sum(mrx26 ) as mrx26 , 
##      sum(mrx27 ) as mrx27 , 
##      sum(mrx28 ) as mrx28 , 
##      sum(mrx29 ) as mrx29 , 
##      sum(mrx30 ) as mrx30 , 
##      sum(mrx31 ) as mrx31 , 
##      sum(mrx32 ) as mrx32 , 
##      sum(mrx33 ) as mrx33 , 
##      sum(mrx34 ) as mrx34 , 
##      sum(mrx35 ) as mrx35 , 
##      sum(mrx36 ) as mrx36 , 
##      sum(mrx37 ) as mrx37 , 
##      sum(mrx38 ) as mrx38 , 
##      sum(mrx39 ) as mrx39 , 
##      sum(mrx40 ) as mrx40 , 
##      sum(mrx41 ) as mrx41 , 
##      sum(mrx42 ) as mrx42 , 
##      sum(mrx43 ) as mrx43 , 
##      sum(mrx44 ) as mrx44 , 
##      sum(mrx45 ) as mrx45 
##  from Staged.cdpsIndicators
##  group by yearEnding
##  ;
## quit;
## proc transpose 
##   data=Work.cdpsIndicatorsSummary 
##   out=Staged.cdpsIndicatorsSummary 
##   name=indicator 
##   prefix=count;
##   by yearEnding nDistinctMembers;
## run;
## 
## 
## /*==============================================================================
## Export dataset as CSV file to be read into R
## ==============================================================================*/
## filename f "&pathData\Staged\cdpsIndicators.csv";
## proc export data=Staged.cdpsIndicators outfile=f dbms=csv replace;
## run;
## 
## 
## /* 
## Make colClasses dataset.
## Output for later use in R.
##  */
## proc contents data=Staged.cdpsIndicators order=varnum out=Work.contents;
## run;
## proc sql;
##   create table Work.colClasses as
##   select
##     varnum,
##     case
##       when prxmatch("/\$/", format) then "character"
##       when prxmatch("/YYMMDD/", format) then "character"
##       when type = 2 then "character"
##       when formatd > 0 then "numeric"
##       else "integer"
##     end as colClass
##   from Work.contents
##   order by
##     varnum
##   ;
## quit;
## filename f "&pathData\Staged\colClasses.csv";
## proc export data=Work.colClasses outfile=f dbms=csv replace;
## run;
## 
## 
## /*==============================================================================
## Export summary as CSV file to be version controlled
## ==============================================================================*/
## filename f "cdpsIndicatorsSummary.csv";
## proc export data=Staged.cdpsIndicatorsSummary outfile=f dbms=csv replace;
## run;
## No errors
## See H:/CHSE/Projects/DataProcessing/ColoradoMedicaid/StagingCode\runCDPS.log for details.
##     user   system  elapsed 
##     0.10     0.13 10670.71

11.1 Read CSV file and merge with member detail

Read the CSV data file created by runCDPS.Rmd and runCDPS.sas.

## The datasets are in E:\Share\DataRepository\Colorado Medicaid\Staged

11.1.1 Member detail

Load mem_detail_Colorado.

f <- file.path(pathStaged, "mem_detail_Colorado.RData")
load(f, verbose=TRUE)
## Loading objects:
##   metadata
##   mem_detail_Colorado

Set key with yearEnding first. We need to carve up the dataset into 12-month lookbacks.

setkey(mem_detail_Colorado, yearEnding, memberID)

11.1.2 CDPS indicators

Read data file.

f <- sprintf("%s\\colClasses.csv", pathStaged)
colClasses <- fread(f)
file.remove(f)
## [1] TRUE
f <- sprintf("%s\\cdpsIndicators.csv", pathStaged)
D0 <- fread(f, colClasses=colClasses[, colClass], na.strings=na.strings, showProgress=FALSE)
D0 <- D0[,
         `:=` (yearEnding = as.Date(yearEnding))]
# str(D0)

Assign the names of the indicators to a character vector. We’ll need this later.

namesInd <- names(D0[, 3:ncol(D0), with=FALSE])

Merge with mem_detail_Colorado.

setkeyv(D0, key(mem_detail_Colorado))
D1 <- merge(mem_detail_Colorado, D0, all.x=TRUE, allow.cartesian=TRUE)

Reset key.

setkey(D1, NULL)

Make sure we didn’t end up with more rows than in mem_detail_Colorado.

n1 <- nrow(mem_detail_Colorado)
n2 <- nrow(D0)
n3 <- nrow(D1)
text <- ifelse(n1 < n3, "increase", ifelse(n1 > n3, "decrease", NA))
isOk <- identical(n1, n3)
if (!isOk) {
  warning(sprintf("The merge between mem_detail_Colorado (%s rows) and cdpsIndicators.csv (%s rows) resulted in an unexpected %s in rows (%s rows, or a %s %s).",
                  format(n1, big.mark=","), 
                  format(n2, big.mark=","), 
                  text, 
                  format(n3, big.mark=","), 
                  format(abs(n3 - n1), big.mark=","), 
                  text))
} else {
  message("All is well.")
}
## All is well.

11.2 Recode NA to 0

Recode the NA values on the indicators to 0. This isn’t a satisfactory solution. Flag to optimize later

for (col in namesInd) {
  D1[is.na(get(col)), (col) := 0]
}

11.3 Save to RData and Stata datasets

The new data table is mem_detail_Colorado_withCDPS with the CDPS indicators added on. Save to a different file instead of overwriting mem_detail_Colorado.RData. Save to the same path as the input CDPS CSV file.

Ignore save.dta13 warning. See this issue.

Save full datasets.

mem_detail_Colorado_withCDPS <- D1
f <- sprintf("%s\\%s", pathStaged, "mem_detail_Colorado_withCDPS")
metadata <- makeMetadata("runCDPS.Rmd")
system.time(save(metadata, mem_detail_Colorado_withCDPS, file=sprintf("%s.RData", f)))
##    user  system elapsed 
##  100.23    0.37  101.38
system.time(save.dta13(mem_detail_Colorado_withCDPS,
                       file=sprintf("%s.dta", f), 
                       convert.dates=TRUE, 
                       compress=TRUE))
##    user  system elapsed 
##  438.84   18.16  460.81
rbind(file.info(sprintf("%s.RData", f))[c("size", "mtime")],
      file.info(sprintf("%s.dta", f))[c("size", "mtime")])
##                                                                                                size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_Colorado_withCDPS.RData   53503715
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_Colorado_withCDPS.dta   1231398794
##                                                                                                        mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_Colorado_withCDPS.RData 2015-07-18 06:34:28
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_Colorado_withCDPS.dta   2015-07-18 06:42:17
# str(mem_detail_Colorado_withCDPS)

Save 5% test sample datasets.

mem_detail_Colorado_withCDPS <- D1[isSample5 == TRUE]
f <- sprintf("%s\\%s", pathStaged, "mem_detail_Colorado_withCDPSSample5")
metadata <- makeMetadata("runCDPS.Rmd")
system.time(save(metadata, mem_detail_Colorado_withCDPS, file=sprintf("%s.RData", f)))
##    user  system elapsed 
##    5.01    0.04    5.12
system.time(save.dta13(mem_detail_Colorado_withCDPS,
                       file=sprintf("%s.dta", f), 
                       convert.dates=TRUE, 
                       compress=TRUE))
##    user  system elapsed 
##   21.07    0.61   21.92
rbind(file.info(sprintf("%s.RData", f))[c("size", "mtime")],
      file.info(sprintf("%s.dta", f))[c("size", "mtime")])
##                                                                                                     size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_Colorado_withCDPSSample5.RData  2804720
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_Colorado_withCDPSSample5.dta   61391958
##                                                                                                               mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_Colorado_withCDPSSample5.RData 2015-07-18 06:42:31
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\mem_detail_Colorado_withCDPSSample5.dta   2015-07-18 06:43:02

Clean up.

rm(mem_detail_Colorado, D0, D1, mem_detail_Colorado_withCDPS)
gc()
##              used   (Mb) gc trigger    (Mb)   max used    (Mb)
## Ncells   28344452 1513.8   53481193  2856.3   53481193  2856.3
## Vcells 1294414457 9875.6 3486894723 26602.9 8330056232 63553.3

12 Merge Oregon Medicaid prices

Before Oregon Medicaid prices are merged on to the Colorado Medicaid claims, we check the match rate of the bucketID variable. I.e., we check how many claims have a corresponding bucketID value on the Oregon Medicaid Master Price List.

12.1 Load the Medicaid pricing tables

Load the Oregon Medicaid Master Price Lists for medical claims and prescription drug claims.

path <- file.path("E:", "Share", "DataRepository", "Medicaid", "Staged")
load(file.path(path, "masterPriceListClaims.RData"), verbose=TRUE)
## Loading objects:
##   dtMasterPriceListClaims
load(file.path(path, "masterPriceListRx.RData"), verbose=TRUE)
## Loading objects:
##   dtMasterPriceListRx

12.2 Medical claims

As a reminder, bucketID is a concatenation of

  • CPT/HCPCS codes (+ pricing modifier)
  • DRG
  • UB revenue code
  • Claim type

Match rates are checked after 4 rounds of bucketID reassignment:

  • Round 0, check match rate of the original bucketID value
  • Round 1, check match rate after the claim type component of bucketID is reassigned to NA for values not matched in Round 0
  • Round 2, check match rate after the DRG component of bucketID is reassigned to NA for values not matched in Round 1
  • Round 3, check match rate after the UB revenue code component of bucketID is reassigned to NA for values not matched in Round 2

Load the Colorado claims data.

f <- sprintf("%s\\%s", pathStaged, "claims_Colorado.RData")
load(f, verbose=TRUE)
## Loading objects:
##   metadata
##   claims
D <- claims

Define the CPT pricing modifiers. A list of CPT/HCPCS pricing modifiers can be found in Understanding Procedural Coding: A Worktext.

pricingModifiers <- c("AA", "AD", "AH", "AJ", "AS", 
                      "GM", 
                      "QB", "QK", "QU", "QX", "QY", "QZ", 
                      "SG", 
                      "TC", 
                      "UN", "UP", "UQ", "UR", "US", 
                      "22", "26", 
                      "50", "51", "52", "53", "54", "55", "56", 
                      "62", "66", 
                      "73", "74", "78", 
                      "80", "82", 
                      "99")

12.2.1 Round 0

Identify which Colorado Medicaid bucket IDs are in the Oregon Medicaid/DMAP Master Price List.

match <- which(D$bucketID %in% dtMasterPriceListClaims$bucketID)
message(sprintf("ROUND 0\n%.2f%% (%s out of %s) of the Colorado Medicaid claims have a bucketID on the Medicaid/DMAP Master Price List.",
                100 * length(match) / nrow(D),
                format(length(match), big.mark=","),
                format(nrow(D), big.mark=",")))
## ROUND 0
## 70.51% (42,320,282 out of 60,023,284) of the Colorado Medicaid claims have a bucketID on the Medicaid/DMAP Master Price List.
nMatch0 <- length(match)

Preserve the original bucketID as a new variable. This will be useful if I need to recover the original value.

D <- D[, bucketID0 := bucketID]

12.2.2 Round 1

For claims with bucket IDs that are not in the Master Price List, reset the bucket ID and force claimType=NA.

D <- D[!match,
       bucketID := paste(ifelse(cptModifier1 %in% pricingModifiers,
                              paste(cpt, cptModifier1, sep="-"),
                              cpt),
                         drg,
                         ubRev,
                         "NA",
                         sep="/")]

Identify which bucket IDs are in the Oregon Medicaid/DMAP Master Price List.

match <- which(D$bucketID %in% dtMasterPriceListClaims$bucketID)
message(sprintf("ROUND 1\n%.2f%% (%s out of %s) of the Colorado Medicaid claims have a bucketID on the Medicaid/DMAP Master Price List.\nIMPROVEMENT\n%.2f%% (%s out of %s)",
                100 * length(match) / nrow(D),
                format(length(match), big.mark=","),
                format(nrow(D), big.mark=","),
                100 * (length(match) - nMatch0) / nMatch0,
                format(length(match) - nMatch0, big.mark=","),
                format(nMatch0, big.mark=",")))
## ROUND 1
## 88.79% (53,296,958 out of 60,023,284) of the Colorado Medicaid claims have a bucketID on the Medicaid/DMAP Master Price List.
## IMPROVEMENT
## 25.94% (10,976,676 out of 42,320,282)
nMatch1 <- length(match)

12.2.3 Round 2

For claims with bucket IDs that are not in the Master Price List, reset the bucket ID and force claimType=NA & drg=NA.

D <- D[!match,
       bucketID := paste(ifelse(cptModifier1 %in% pricingModifiers,
                              paste(cpt, cptModifier1, sep="-"),
                              cpt),
                         "NA",
                         ubRev,
                         "NA",
                         sep="/")]

Identify which bucket IDs are in the Oregon Medicaid/DMAP Master Price List.

match <- which(D$bucketID %in% dtMasterPriceListClaims$bucketID)
message(sprintf("ROUND 2\n%.2f%% (%s out of %s) of the Colorado Medicaid claims have a bucketID on the Medicaid/DMAP Master Price List.\nIMPROVEMENT\n%.2f%% (%s out of %s)",
                100 * length(match) / nrow(D),
                format(length(match), big.mark=","),
                format(nrow(D), big.mark=","),
                100 * (length(match) - nMatch1) / nMatch1,
                format(length(match) - nMatch1, big.mark=","),
                format(nMatch1, big.mark=",")))
## ROUND 2
## 88.84% (53,322,267 out of 60,023,284) of the Colorado Medicaid claims have a bucketID on the Medicaid/DMAP Master Price List.
## IMPROVEMENT
## 0.05% (25,309 out of 53,296,958)
nMatch2 <- length(match)

12.2.4 Round 3

For claims with bucket IDs that are not in the Master Price List, reset the bucket ID and force claimType=NA, drg=NA, & ubRev=NA.

D <- D[!match,
       bucketID := paste(ifelse(cptModifier1 %in% pricingModifiers,
                              paste(cpt, cptModifier1, sep="-"),
                              cpt),
                         "NA",
                         "NA",
                         "NA",
                         sep="/")]

Identify which bucket IDs are in the Oregon Medicaid/DMAP Master Price List.

match <- which(D$bucketID %in% dtMasterPriceListClaims$bucketID)
message(sprintf("ROUND 3\n%.2f%% (%s out of %s) of the Colorado Medicaid claims have a bucketID on the Medicaid/DMAP Master Price List.\nIMPROVEMENT\n%.2f%% (%s out of %s)",
                100 * length(match) / nrow(D),
                format(length(match), big.mark=","),
                format(nrow(D), big.mark=","),
                100 * (length(match) - nMatch2) / nMatch2,
                format(length(match) - nMatch2, big.mark=","),
                format(nMatch2, big.mark=",")))
## ROUND 3
## 97.21% (58,349,987 out of 60,023,284) of the Colorado Medicaid claims have a bucketID on the Medicaid/DMAP Master Price List.
## IMPROVEMENT
## 9.43% (5,027,720 out of 53,322,267)
nMatch3 <- length(match)

12.2.5 Final match rate

message(sprintf("FINAL MATCH RATE\n%.2f%% (%s out of %s) of the Colorado Medicaid claims have a bucketID on the Medicaid/DMAP Master Price List.\nMATCH FAILURE RATE\n%.2f%% (%s out of %s)",
                100 * length(match) / nrow(D),
                format(length(match), big.mark=","),
                format(nrow(D), big.mark=","),
                100 * (nrow(D) - length(match)) / nrow(D),
                format(nrow(D) - length(match), big.mark=","),
                format(nrow(D), big.mark=",")))
## FINAL MATCH RATE
## 97.21% (58,349,987 out of 60,023,284) of the Colorado Medicaid claims have a bucketID on the Medicaid/DMAP Master Price List.
## MATCH FAILURE RATE
## 2.79% (1,673,297 out of 60,023,284)

Make data table of unmatched bucketID values.

matchFail <- D[!match,
               list(countClaims = .N),
               list(bucketID0,
                    bucketID,
                    cpt,
                    drg,
                    ubRev,
                    claimType)]
matchFail <- matchFail[order(countClaims, decreasing=TRUE)]
matchFail <- matchFail[, propFailures := countClaims / sum(countClaims)]
matchFailClaims <- matchFail

12.2.6 Merge prices

Merge the bucketUnitPrice from the Oregon Medicaid Master Price List to the Colorado claims.

if (key(dtMasterPriceListClaims) != "bucketID") {
  setkey(dtMasterPriceListClaims, bucketID)
}
if (!identical(key(dtMasterPriceListClaims), key(D))) {
  setkeyv(D, key(dtMasterPriceListClaims))
}
D <- merge(D,
           dtMasterPriceListClaims[, list(bucketID, bucketUnitPrice)],
           all.x=TRUE)

Check.

nUnitPriceNA <- length(D[is.na(bucketUnitPrice), bucketUnitPrice])
if (nrow(D) - length(match) != nUnitPriceNA) {
  warning(sprintf("Merge produced UNEXPECTED results\n%s rows expected to have missing bucketUnitPrices\n%s rows actually having missing bucketUnitPrices",
                  format(nrow(D) - length(match), big.mark=","),
                  format(nUnitPriceNA, big.mark=",")))
} else {
  message(sprintf("Merge produced EXPECTED results\n%s rows expected to have missing bucketUnitPrices\n%s rows actually having missing bucketUnitPrices",
                  format(nrow(D) - length(match), big.mark=","),
                  format(nUnitPriceNA, big.mark=",")))
}
## Merge produced EXPECTED results
## 1,673,297 rows expected to have missing bucketUnitPrices
## 1,673,297 rows actually having missing bucketUnitPrices

Add on the imputed prices.

Preserving this email exchange with John for posterity…

From: John McConnell   
Sent: Wednesday, November 12, 2014 12:02 PM  
To: Benjamin Chan; Stephanie Renfro  
Subject: RE: data/variable request  

Ok â<U+0080><U+0093> on these other points, I think let's make this change

For Medicaid,  amtAllowedRepriced = amtAllowedEstimated2 [YES]

For Commercial/APAC, amtAllowedRepriced = amtAllowedImputed [NO -  I THINK IT
SHOULD BE amtAllowedRepriced = amtPaidImputed]

Other indicator flags sound good.

From: John McConnell   
Sent: Wednesday, November 12, 2014 11:59 AM  
To: Benjamin Chan; Stephanie Renfro  
Subject: RE: data/variable request  

Ok, great, glad we are getting clarity. For the Medicaid analyses, we should not
include anything on OOP.

Rationale:

Suppose a Medicaid person gets a service designated as CPT code 12345 which is
paid $100 (bucketUnitPrice).

If a commercial person gets the same service, we want to price that at the
same rate. So if the commercial person has 5 visits and the Medicaid person
has 5 visits, we value those at the same amount ($500), which represents what
Medicaid would have paid if it were covering the private person.

The reason we wouldn't want to analyze amtAllowedImputed if it included amtOOP
is that the amtOOP can be quite high. So in the example above, it could be
that the person paid $200 OOP for CPT 12345. If we follow the
amtAllowedImputed algorithm then we price that at $200 + $100 = $300, which is
not close to the Medicaid world. I would maintain that the value we're
interested in is simply the repriced version â<U+0080><U+0093> not including amtOOP. (It's not
clear what it means to me to have a service priced at a Medicaid price but
then also add on the commercial out of pocket amount).

SO â<U+0080><U+0093> for Medicaid-based analyses, we should focus on this:

amtAllowedRepriced := sign(amtPaid) * bucketUnitPrice * qtyUnitsBilled

If, on the other hand, we want to know how is being spent on healthcare in the
commercial world (e.g. for SHEW), we should focus on the actual amtPaid and
actual amtOOP.
  1. If the CPT code is in {J7187, J7192, J7195}, do not impute. Set amtAllowedRepriced to the same value as amtPaid.
regex <- "^J7187|^J7192|^J7195"
D <- D[grepl(regex, cpt),
       amtAllowedRepriced := amtPaid]

1.1. If qtyUnitsBilled is NA, then recode qtyUnitsBilled to +1.

This scenario shows up in the Colorado claims data.

D[, list(countRows = .N), list(isQtyMissing = is.na(qtyUnitsBilled))]
##    isQtyMissing countRows
## 1:        FALSE  60023284
D <- D[is.na(qtyUnitsBilled),
       qtyUnitsBilled := 1]
  1. If the CPT code is not in {J7187, J7192, J7195} and the bucket ID is in our master Medicaid Price List, set the imputed price as qty * Medicaid unit price.
D <- D[, signQty := sign(qtyUnitsBilled)]
D <- D[, hasCorrespondingOregonPrice := is.finite(bucketUnitPrice)]
D <- D[!grepl(regex, cpt) & hasCorrespondingOregonPrice == TRUE & !qtyUnitsBilled==0,
       amtAllowedRepriced := bucketUnitPrice * qtyUnitsBilled]
D[!grepl(regex, cpt),
  list(sumAmtAllowedRepriced = sum(amtAllowedRepriced, na.rm=TRUE),
       countRows = .N),
  signQty]
##    signQty sumAmtAllowedRepriced countRows
## 1:       1           47430775307  53481583
## 2:      -1           -3525351037   6541631
  1. If all the conditions above are true but qtyUnitsBilled = 0, default to the assumption that qtyUnitsBilled = 1 and use the sign of the net sum of the cost variables to determine the sign of the imputed amount (positive/negative).

Note: amtDeduct, amtCoins, and amtOOP do not exist in the Colorado data (unlike the Oregon APAC data).

D <- D[,
       signNetCost := sign(rowSums(D[, list(amtPaid, amtCopay)], na.rm=TRUE))]
D <- D[!grepl(regex, cpt) & hasCorrespondingOregonPrice == TRUE & qtyUnitsBilled==0,
       amtAllowedRepriced := signNetCost * bucketUnitPrice]
D[!grepl(regex, cpt),
  list(sumAmtAllowedRepriced = sum(amtAllowedRepriced, na.rm=TRUE),
       countRows = .N),
  list(signQty, signNetCost)][order(signQty, signNetCost)]
##    signQty signNetCost sumAmtAllowedRepriced countRows
## 1:      -1          -1         -3.525334e+09   6540941
## 2:      -1           0         -3.761600e+02        22
## 3:      -1           1         -1.686087e+04       668
## 4:       1          -1          3.076379e+08     40010
## 5:       1           0          2.919000e+03        55
## 6:       1           1          4.712313e+10  53441518
  1. If, when applying #3, it turns out that the sign of the net sum of the cost variables is 0 (because all the cost variables are 0 or NA), assume the imputed amount should be positive. This is per the advice of Cindi McElhaney, Q Corp Senior Health Care Analyst and former analyst at a major health plan.
From: Cindi McElhaney [mailto:Cindi.McElhaney@q-corp.org] 
Sent: Wednesday, March 18, 2015 2:51 PM
To: Stephanie Renfro
Subject: RE: Time for a quick call?

Positive imputed amount.

From: Stephanie Renfro [mailto:renfrst@ohsu.edu] 
Sent: Wednesday, March 18, 2015 2:50 PM
To: Cindi McElhaney
Subject: RE: Time for a quick call?

Not burdensome, but impossible. OHA won't identify health plans in their research datasets. Since I'm forced to make an assumption, in your expert opinion is it better to assume a positive imputed amount or to impute to $0?

From: Cindi McElhaney [mailto:Cindi.McElhaney@q-corp.org] 
Sent: Wednesday, March 18, 2015 2:41 PM
To: Stephanie Renfro
Subject: RE: Time for a quick call?

Yes to the first 2.

Are there particular data suppliers who have 0s for the encounters? I would assume positive, but it might be worth checking if not too burdensome.

From: Stephanie Renfro [mailto:renfrst@ohsu.edu] 
Sent: Wednesday, March 18, 2015 1:42 PM
To: Cindi McElhaney
Subject: RE: Time for a quick call?

One follow-up question.

When qtyUnitsBilled = 0, I'm using the default qty as 1 and make the imputed value positive if (amtPaid + amtDeduct + amtCoins + amtCopay + amtOOP) > 0.

When qtyUnitsBilled = 0, I'm using the default as 1 and make the imputed value negative if (amtPaid + amtDeduct + amtCoins + amtCopay + amtOOP) < 0.

What if all the cost variables are 0 or NA - as is the case in many encounter claims? Safe to assume the imputed value should be positive? Or not okay to make assumptions?
D <- D[!grepl(regex, cpt) & hasCorrespondingOregonPrice==TRUE & qtyUnitsBilled==0 & signNetCost==0,
       amtAllowedRepriced := bucketUnitPrice]
D[!grepl(regex, cpt), 
  list(sumAmtAllowedRepriced = sum(amtAllowedRepriced, na.rm=TRUE),
       countRows = .N),
  list(signQty, signNetCost)][order(signQty, signNetCost)]
##    signQty signNetCost sumAmtAllowedRepriced countRows
## 1:      -1          -1         -3.525334e+09   6540941
## 2:      -1           0         -3.761600e+02        22
## 3:      -1           1         -1.686087e+04       668
## 4:       1          -1          3.076379e+08     40010
## 5:       1           0          2.919000e+03        55
## 6:       1           1          4.712313e+10  53441518

Drop unneeded sign variables.

D <- D[,
       `:=` (signNetCost = NULL,
             signQty = NULL)]

Check missingness. Summary table should only have 2 rows. Otherwise, some claims without a corresponding Oregon price did not get imputed/repriced.

D[,
  .N,
  list(isMissImputed = is.na(amtAllowedRepriced),
       hasCorrespondingOregonPrice)][, prop := N / sum(N)]
##    isMissImputed hasCorrespondingOregonPrice        N       prop
## 1:          TRUE                       FALSE  1673297 0.02787747
## 2:         FALSE                        TRUE 58349987 0.97212253

12.2.7 Save to RData and Stata datasets

Save full datasets.

claims <- D
f <- sprintf("%s\\%s", pathStaged, "claims_Colorado")
metadata <- makeMetadata("mergePrices.Rmd")
system.time(save(metadata, claims, file=sprintf("%s.RData", f)))
##    user  system elapsed 
## 1699.84    8.83 1724.52
system.time(save.dta13(claims, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
## 5642.29  224.40 5918.82
rbind(file.info(sprintf("%s.RData", f))[c("size", "mtime")],
      file.info(sprintf("%s.dta", f))[c("size", "mtime")])
##                                                                                    size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_Colorado.RData  1133641389
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_Colorado.dta   16806535282
##                                                                                           mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_Colorado.RData 2015-07-18 07:44:07
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_Colorado.dta   2015-07-18 09:23:06
# str(claims)

Save 5% test sample datasets.

claims <- D[isSample5 == TRUE]
f <- sprintf("%s\\%s", pathStaged, "claims_ColoradoSample5")
metadata <- makeMetadata("mergePrices.Rmd")
system.time(save(metadata, claims, file=sprintf("%s.RData", f)))
##    user  system elapsed 
##   83.65    0.35   84.81
system.time(save.dta13(claims, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
##  278.64   10.81  291.66
rbind(file.info(sprintf("%s.RData", f))[c("size", "mtime")],
      file.info(sprintf("%s.dta", f))[c("size", "mtime")])
##                                                                                         size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_ColoradoSample5.RData  60145635
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_ColoradoSample5.dta   828184854
##                                                                                                  mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_ColoradoSample5.RData 2015-07-18 09:25:01
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\claims_ColoradoSample5.dta   2015-07-18 09:30:08

Clean up.

rm(claims)
gc()
##              used    (Mb)  gc trigger    (Mb)   max used    (Mb)
## Ncells   31454641  1679.9    53481193  2856.3   53481193  2856.3
## Vcells 4850296360 37004.9 10844613470 82737.9 9832373287 75015.1

12.3 Prescription drug claims

As a reminder, bucketID is simply

  • NDC code

Load the Colorado claims data.

f <- sprintf("%s\\%s", pathStaged, "rxClaims_Colorado.RData")
load(f, verbose=TRUE)
## Loading objects:
##   metadata
##   rxClaims
D <- rxClaims

Identify which Colorado Medicaid bucket IDs are in the Oregon Medicaid/DMAP Master Price List.

match <- which(D$bucketID %in% dtMasterPriceListRx$bucketID)
message(sprintf("FINAL MATCH RATE\n%.2f%% (%s out of %s) of the Colorado Medicaid Rx claims have a bucketID on the Medicaid/DMAP Master Price List.\nMATCH FAILURE RATE\n%.2f%% (%s out of %s)",
                100 * length(match) / nrow(D),
                format(length(match), big.mark=","),
                format(nrow(D), big.mark=","),
                100 * (nrow(D) - length(match)) / nrow(D),
                format(nrow(D) - length(match), big.mark=","),
                format(nrow(D), big.mark=",")))
## FINAL MATCH RATE
## 99.27% (15,586,503 out of 15,701,649) of the Colorado Medicaid Rx claims have a bucketID on the Medicaid/DMAP Master Price List.
## MATCH FAILURE RATE
## 0.73% (115,146 out of 15,701,649)

Make data table of unmatched bucketID values.

matchFail <- D[!match,
               list(countClaims = .N),
               list(bucketID,
                    ndc)]
matchFail <- matchFail[order(countClaims, decreasing=TRUE)]
matchFail <- matchFail[, propFailures := countClaims / sum(countClaims)]
matchFailRx <- matchFail

12.3.1 Merge prices

Merge the bucketUnitPrice from the Oregon Medicaid Master Price List to the Colorado claims.

if (key(dtMasterPriceListRx) != "bucketID") {
  setkey(dtMasterPriceListRx, bucketID)
}
if (!identical(key(dtMasterPriceListRx), key(D))) {
  setkeyv(D, key(dtMasterPriceListRx))
}
D <- merge(D,
           dtMasterPriceListRx[, list(bucketID, bucketUnitPrice)],
           all.x=TRUE)

Check.

nUnitPriceNA <- length(D[is.na(bucketUnitPrice), bucketUnitPrice])
if (nrow(D) - length(match) != nUnitPriceNA) {
  warning(sprintf("Merge produced UNEXPECTED results\n%s rows expected to have missing bucketUnitPrices\n%s rows actually having missing bucketUnitPrices",
                  format(nrow(D) - length(match), big.mark=","),
                  format(nUnitPriceNA, big.mark=",")))
} else {
  message(sprintf("Merge produced EXPECTED results\n%s rows expected to have missing bucketUnitPrices\n%s rows actually having missing bucketUnitPrices",
                  format(nrow(D) - length(match), big.mark=","),
                  format(nUnitPriceNA, big.mark=",")))
}
## Merge produced EXPECTED results
## 115,146 rows expected to have missing bucketUnitPrices
## 115,146 rows actually having missing bucketUnitPrices

Calculate imputed and estimated amounts.

D <- D[, hasCorrespondingOregonPrice := is.finite(bucketUnitPrice)]
D <- D[hasCorrespondingOregonPrice == TRUE,
       amtAllowedRepriced := bucketUnitPrice * qtyDispensed]

Note, if the qtyDispensed is 0, our imputed estimated amount comes to 0. We do not default the quantity to 1 as for medical spending above.

D[,
  .N,
  list(isQtyZero = qtyDispensed == 0,
       isQtyMissing = is.na(qtyDispensed))]
##    isQtyZero isQtyMissing        N
## 1:      TRUE        FALSE    94100
## 2:     FALSE        FALSE 15607549

Check missingness. Summary table should only have 2 rows. Otherwise, some claims without a corresponding Oregon price did not get imputed/repriced.

D[,
  .N,
  list(isMissImputed = is.na(amtAllowedRepriced),
       hasCorrespondingOregonPrice)][, prop := N / sum(N)]
##    isMissImputed hasCorrespondingOregonPrice        N       prop
## 1:         FALSE                        TRUE 15580895 0.99230947
## 2:          TRUE                       FALSE   120754 0.00769053

12.3.2 Save to RData and Stata datasets

Save full datasets.

rxClaims <- D
f <- sprintf("%s\\%s", pathStaged, "rxClaims_Colorado")
metadata <- makeMetadata("mergePrices.Rmd")
system.time(save(metadata, rxClaims, file=sprintf("%s.RData", f)))
##    user  system elapsed 
##  377.65    2.73  384.67
system.time(save.dta13(rxClaims, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
## 1248.57   39.92 1302.84
rbind(file.info(sprintf("%s.RData", f))[c("size", "mtime")],
      file.info(sprintf("%s.dta", f))[c("size", "mtime")])
##                                                                                     size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\rxClaims_Colorado.RData  417207496
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\rxClaims_Colorado.dta   3203143958
##                                                                                             mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\rxClaims_Colorado.RData 2015-07-18 09:40:52
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\rxClaims_Colorado.dta   2015-07-18 10:02:54
# str(rxClaims)

Save 5% test sample datasets.

rxClaims <- D[isSample5 == TRUE]
f <- sprintf("%s\\%s", pathStaged, "rxClaims_ColoradoSample5")
metadata <- makeMetadata("mergePrices.Rmd")
system.time(save(metadata, rxClaims, file=sprintf("%s.RData", f)))
##    user  system elapsed 
##   18.30    0.11   18.72
system.time(save.dta13(rxClaims, file=sprintf("%s.dta", f), convert.dates=TRUE, compress=TRUE))
##    user  system elapsed 
##   55.37    1.95   57.94
rbind(file.info(sprintf("%s.RData", f))[c("size", "mtime")],
      file.info(sprintf("%s.dta", f))[c("size", "mtime")])
##                                                                                           size
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\rxClaims_ColoradoSample5.RData  21107415
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\rxClaims_ColoradoSample5.dta   159387866
##                                                                                                    mtime
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\rxClaims_ColoradoSample5.RData 2015-07-18 10:03:35
## E:\\Share\\DataRepository\\Colorado Medicaid\\Staged\\rxClaims_ColoradoSample5.dta   2015-07-18 10:04:52

Clean up.

rm(rxClaims)
gc()
##              used    (Mb) gc trigger    (Mb)   max used    (Mb)
## Ncells   49780204  2658.6   71941987  3842.2   71941987  3842.2
## Vcells 1739830578 13273.9 5552442096 42361.8 9832373287 75015.1

12.4 Save match failure datasets

Save match failure summary datasets for later investigation.

f <- sprintf("%s\\%s", pathStaged, "mergePricesMatchFailures.RData")
metadata <- makeMetadata("mergePrices.Rmd")
save(metadata, matchFailClaims, matchFailRx, file=f)

13 File info

Dump results of file.info(list.files()) to a text file for version controlling.

setwd(pathStaged)
fileInfo <- file.info(list.files(pathStaged))
filename <- rownames(fileInfo)
setwd(pathScripts)
f <- file.path(getwd(), "fileInfo.csv")
fileInfo[, c("size", "mtime")]
##                                                  size               mtime
## cdpsIndicators.csv                         1852201345 2015-07-18 06:27:56
## cdpsindicators.sas7bdat                    7019709440 2015-07-18 06:23:31
## cdpsindicatorssummary.sas7bdat                  78848 2015-07-18 06:24:17
## claims.sas7bdat                           14048904192 2015-07-17 17:32:13
## claims.sas7bndx                            1638962176 2015-07-17 17:32:13
## claims_Colorado.dta                       16806535282 2015-07-18 09:23:06
## claims_Colorado.RData                      1133641389 2015-07-18 07:44:07
## claims_ColoradoSample5.dta                  828184854 2015-07-18 09:30:08
## claims_ColoradoSample5.RData                 60145635 2015-07-18 09:25:01
## clientSnapshot.csv                         6032779299 2015-07-17 16:16:05
## clientSnapshot.dta                         2263290722 2015-07-17 17:05:00
## clientSnapshot.RData                         22039663 2015-07-17 16:56:01
## clientsnapshot.sas7bdat                    6395298816 2015-07-17 16:11:02
## clientsnapshot.sas7bndx                    1049248768 2015-07-17 16:11:02
## clientSnapshotSample5.dta                   112401570 2015-07-17 17:10:17
## clientSnapshotSample5.RData                   1181399 2015-07-17 17:09:49
## colclasses.sas7bdat                              5120 2015-07-17 21:12:03
## Cont_En_LU.RData                              4685959 2015-07-17 16:51:49
## diagnosisCodes.dta                         5375570712 2015-07-18 00:23:29
## diagnosisCodes.RData                        463993770 2015-07-17 23:57:49
## diagnosiscodes.sas7bdat                   24670422016 2015-07-17 22:47:01
## diagnosiscodes.sas7bndx                    2818962432 2015-07-17 22:47:01
## diagnosisCodesSample5.dta                   259848544 2015-07-18 00:25:58
## diagnosisCodesSample5.RData                  23868796 2015-07-18 00:24:33
## formats.sas7bcat                             56214528 2015-07-17 15:56:30
## mem_detail_Colorado.dta                     929032554 2015-07-18 03:29:18
## mem_detail_Colorado.RData                    22752509 2015-07-18 03:25:33
## mem_detail_Colorado_withCDPS.dta           1231398794 2015-07-18 06:42:17
## mem_detail_Colorado_withCDPS.RData           53503715 2015-07-18 06:34:28
## mem_detail_Colorado_withCDPSSample5.dta      61391958 2015-07-18 06:43:02
## mem_detail_Colorado_withCDPSSample5.RData     2804720 2015-07-18 06:42:31
## mem_detail_ColoradoSample5.dta               46270478 2015-07-18 03:29:48
## mem_detail_ColoradoSample5.RData               880388 2015-07-18 03:29:30
## Member_Months_LU.RData                        4624609 2015-07-17 16:49:27
## mergePricesMatchFailures.RData                  89391 2015-07-18 10:05:13
## procedureCodes.dta                           20796586 2015-07-18 00:23:56
## procedureCodes.RData                          3674570 2015-07-18 00:23:42
## procedurecodes.sas7bdat                     138298368 2015-07-17 22:47:01
## procedurecodes.sas7bndx                      22459392 2015-07-17 22:47:01
## procedureCodesSample5.dta                     1018674 2015-07-18 00:26:17
## procedureCodesSample5.RData                    192410 2015-07-18 00:26:07
## rxclaims.sas7bdat                          4677403648 2015-07-17 21:12:03
## rxclaims.sas7bndx                          1125356544 2015-07-17 21:12:03
## rxClaims_Colorado.dta                      3203143958 2015-07-18 10:02:54
## rxClaims_Colorado.RData                     417207496 2015-07-18 09:40:52
## rxClaims_ColoradoSample5.dta                159387866 2015-07-18 10:04:52
## rxClaims_ColoradoSample5.RData               21107415 2015-07-18 10:03:35
message(sprintf("The above contents were dumped to file:\n%s", basename(f)))
## The above contents were dumped to file:
## fileInfo.csv
write.csv(data.frame(filename = filename,
                     size = fileInfo$size,
                     modificationTime = fileInfo$mtime), 
          file=f, 
          quote=FALSE,
          row.names=FALSE)

14 Copy datasets

Copy Stata .dta datasets to the Transfer folder for Rich and Jodi.

files <- list.files(pathStaged)[grep(".dta", list.files(pathStaged))]
pathTransfer <- "E:\\Share\\Transfer\\UCDenver\\Staged"
from <- sprintf("%s\\%s", pathStaged, files)
to <- sprintf("%s\\%s", pathTransfer, files)
file.copy(from, to, overwrite=TRUE)
##  [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
setwd(pathTransfer)
fileInfo <- file.info(list.files(pathTransfer))
filename <- rownames(fileInfo)
setwd(path)
f <- file.path(pathTransfer, "fileInfo.csv")
fileInfo[, c("size", "mtime")]
##                                                size               mtime
## claims_Colorado.dta                     16806535282 2015-07-18 10:06:46
## claims_ColoradoSample5.dta                828184854 2015-07-18 10:06:50
## clientSnapshot.dta                       2263290722 2015-07-18 10:06:59
## clientSnapshotSample5.dta                 112401570 2015-07-18 10:06:59
## diagnosisCodes.dta                       5375570712 2015-07-18 10:07:22
## diagnosisCodesSample5.dta                 259848544 2015-07-18 10:07:23
## fileInfo.csv                                    866 2015-07-17 08:40:25
## mem_detail_Colorado.dta                   929032554 2015-07-18 10:07:26
## mem_detail_Colorado_withCDPS.dta         1231398794 2015-07-18 10:07:31
## mem_detail_Colorado_withCDPSSample5.dta    61391958 2015-07-18 10:07:32
## mem_detail_ColoradoSample5.dta             46270478 2015-07-18 10:07:32
## procedureCodes.dta                         20796586 2015-07-18 10:07:32
## procedureCodesSample5.dta                   1018674 2015-07-18 10:07:32
## rxClaims_Colorado.dta                    3203143958 2015-07-18 10:07:45
## rxClaims_ColoradoSample5.dta              159387866 2015-07-18 10:07:45
message(sprintf("The above contents were dumped to file:\n%s", f))
## The above contents were dumped to file:
## E:\Share\Transfer\UCDenver\Staged/fileInfo.csv
write.csv(data.frame(filename = filename,
                     size = fileInfo$size,
                     modificationTime = fileInfo$mtime), 
          file=f, 
          quote=FALSE,
          row.names=FALSE)

15 Notes

15.1 Information about provider ID

From: Burton, Byron [mailto:byron.burton@state.co.us] 
Sent: Wednesday, June 03, 2015 9:29 AM
To: Lindrooth, Richard; Duke, Jodi Kay; Benjamin Chan; John McConnell
Cc: Ly, Melissa; Dalzell, Joel; Whalen, Tom
Subject: RE: CU Denver/CO Medicaid Data Extract - Followup Call (Provider Information)

Responses in red below. thx

Byron Burton
Health Data Strategy
Colorado Department of Health Care Policy and Financing
P 303.866.2481
Byron.Burton@state.co.us

This email message and any included attachments, from the Colorado Department of Health Care Policy and Financing, are confidential and intended solely for the use of the individual or entity to which it is addressed. The information contained herein may include protected health information or otherwise privileged information. Unauthorized review, forwarding, printing, copying, distributing, or using such information is strictly prohibited and may be unlawful. If you received this message in error, please notify the sender by replying to this message and delete the email without disclosure. Thank you. 

From: Lindrooth, Richard [mailto:RICHARD.LINDROOTH@UCDENVER.EDU] 
Sent: Tuesday, June 02, 2015 6:06 PM
To: Duke, Jodi Kay; Benjamin Chan (chanb@ohsu.edu); John McConnell; Burton, Byron; Ly, Melissa; Dalzell, Joel; Whalen, Tom
Subject: RE: CU Denver/CO Medicaid Data Extract - Followup Call (Provider Information)

Hello, Weâ<U+0080><U+0099>ve been able to sort through a number of issues with the provider data but still have a few remaining questions.  It may be that these could be answered via e-mail and a call isnâ<U+0080><U+0099>t necessary. Let me know if it makes sense to talk given these questions, if not we can cancel the call. 
 
 
1.      Questions about Provider IDs:
a.      Providers often bill under a separate provider ID (prov_bill_id).  It appears that prov_id=prov_bill_id for many providers but is there a file that links individual provider idâ<U+0080><U+0099>s to the billing ID used for their services?  For example University Physicians is an all-encompassing billing ID but individual UPI physicians may have separate provider IDs and Tax IDs. It is too bad the rendering provider information is not universally available.  It there a systematic reason why it doesnâ<U+0080><U+0099>t always appear on the claim? 
â<U+0080>¢        I believe (fairly certain) the only provider id currently required to pay a claim is billing id.  The major implications of this (perhaps you all can think of others)â<U+0080>¦
o   The incentive to provide accurate rendering, attending, referring,  provider id  information is minimal, I would estimate
o   Variation very likely exists between billing organizations (billing systems) with regard to accuracy, consistency, validity, completeness, etc. of provider information outside of the required billing id
â<U+0080>¢        For professional claims there is a greater likelihood that bill provider id = rend provider id (but certainly not always, i.e. several practices may use one billing center)
â<U+0080>¢        Donâ<U+0080><U+0099>t think rendering id is captured on facility claims
â<U+0080>¢        Think Attending ID is only captured on facility claims.  Not saying it is captured consistently (that is a separate question), only that if it is captured at all it would be on facility claims
â<U+0080>¢        There are also very unusual billing providers in our data (Medical device providers, bus service providers for transportation, etc.)
â<U+0080>¢        All of the above are testable with the data you have.  If you find an inconsistency between my response and actual data, of course disregard my response.
 
b.      What happens when a clinician changes position and their address changes? Does the new address get updated in the provider files? Is there historical address information?
â<U+0080>¢         The vast majority of providers are paid electronically (Iâ<U+0080><U+0099>ll say 98%, but it could be higher than that).
o   For this reason there is no direct tangible incentive for providers to keep demographic or address information current
o   There is a provider span table that has active/ non-active historical status.  Including this table might add more confusion than clarity.  A better way to assess provider activity is simply to create a provider table based upon claims activity (information that you currently already have)

c.      Is there any other provider information available? 
â<U+0080>¢        There is a very confusing table that links all bill provider ids to all rendering provider ids (and maybe attending and referring as well).  If you need this information, It would probably be much easier to create this table yourselves by grouping all billing provider idâ<U+0080><U+0099>s by all non-null provider ids found in any of the other provider fields.  
â<U+0080>¢        There may be some one-off provider tables that were used for very specific purposes (that I donâ<U+0080><U+0099>t have on the tip of my mind) that have not been included in your data

â<U+0080>¢        We are going through a very exciting provider re-enrollment process as part of our new Medicaid Management Information System (MMIS) implementation (new MMIS is called Colorado Interchange).  All providers will need to re-enroll with their NPI ID, and we will be paying claims at the NPI ID level.  This means much more granular and meaningful provider data for future analytics.  The process is scheduled for March 31, 2016 (I wouldnâ<U+0080><U+0099>t be surprised of delays, this is an intensive effort for providers).  Unfortunately, that timeline is probably well outside the timeline of your work.
2.      Data refresh/update
a.      Timing (July - October)  If we waited until October 2015 would we have a reasonable complete set of claims through 6/30/15?
b.      Could we also get client_prog_aid_cat and clnt_fpl_pct on the new data?
â<U+0080>¢        Yes, for the completeness question
â<U+0080>¢        Not sure.  Can you check with Joel about having fields added to the feed? There may be broader implications since we use the feed for other purposes also.  From a technical perspective it isnâ<U+0080><U+0099>t difficult. Or even as separate supplementary files.
 
Thanks!
Rich

16 Session info

## Start time: 2015-07-17 15:56:25
## End time: 2015-07-18 10:09:04
## Time difference of 18.21082 hours
##                      sysname                      release 
##                    "Windows"            "Server 2008 x64" 
##                      version                     nodename 
## "build 7601, Service Pack 1"                       "CHSE" 
##                      machine                        login 
##                     "x86-64"                      "chanb" 
##                         user               effective_user 
##                      "chanb"                      "chanb"
## R version 3.1.2 (2014-10-31)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] xlsx_0.5.7       xlsxjars_0.6.1   rJava_0.9-6      sas7bdat_0.5    
## [5] readstata13_0.7  foreign_0.8-62   data.table_1.9.4 chse_0.6        
## [9] DiagrammeR_0.7  
## 
## loaded via a namespace (and not attached):
##  [1] chron_2.3-45    digest_0.6.8    evaluate_0.5.5  formatR_1.0    
##  [5] htmltools_0.2.6 htmlwidgets_0.5 jsonlite_0.9.16 knitr_1.9      
##  [9] magrittr_1.5    plyr_1.8.1      Rcpp_0.11.6     reshape2_1.4.1 
## [13] rmarkdown_0.5.1 rstudioapi_0.2  stringi_0.5-5   stringr_1.0.0  
## [17] tools_3.1.2     yaml_2.1.13